The Pragmatic Craftsman :: Simplicity from complexity : by Stanley Kubasek ::

Java Inner Classes – Part 3 – Nested Classes

In Part 1, I’ve covered the basics, in part 2, anonymous inner classes. Is there anything left about inner classes? Yes, there is. I warned you that inner classes are a beast. :-)

In this part, I’ll cover nested classes.

When you create an inner class, there is a connection between the enclosed class and the inner class. Because of that, the inner class can access and manipulate the enclosed class.

Take that connection away and you have a nested class. A nested class is a static inner class. With a nested class, 1) you don’t need an outer class to create the instance and 2) you can’t access non-static outer-class object from the nested instance. Below is an example.

public class StaticInner {
  String s = "test";

  public static class Inner {
    private int counter = 1;
    public int increment() {
       return counter++;
    }

    public void printS() {
      // StaticInner.this.s;
      // ERROR: No enclosing instance of the type StaticInner is
      // accessible in scope
    }
  }

public static class Inner2 {
  private static int counter = 1;
  public static int increment() {
    return counter++;
  }
}

public static class Inner3 {
  public static class Inner3Inner {
    public void sayHi() {
      System.out.println("Hi");
    }
  }
}

public static void main(String[] args) {
  System.out.println("Inner");
  Inner inner = new Inner();
  System.out.println(inner.increment());  // "1"
  System.out.println(inner.increment()); "2"
  Inner inner2 = new Inner();
  System.out.println(inner2.increment()); // "1"

  // Inner2 has a static method
  System.out.println("Inner2");
  System.out.println(Inner2.increment()); // "1"
  System.out.println(Inner2.increment()); // "2"
  // Inner3 has an inner class
  System.out.println("Inner3Inner");
  Inner3Inner subInner = new Inner3Inner();
  subInner.sayHi(); // "Hi"
  }
}

In the main method, you can see that you can just instantiate Inner with new Inner(). Also in Inner, printS method tries to access StaticInner variable but it’s not allowed to. There is no connection between the two classes.

Initially, I thought a “static class” can have only one instance. That’s not true. Inner can have multiple instances, inner2 is a seperate instance and has its own object.

Inner2 is an example of a static instance. You can refer to in directly by Inner2.increment().

Inner2 shows that static inners can have more than one layer, Inner3Inner is defined inside Inner3.

Classes inside interfaces

Yes, you read that correctly. You can have an inner class within an interface! I did not know this was possible. Not that I would want to use it, but still… Take a look at the following example.

// Thinking in Java example
public interface ClassInInterface {
  void howdy();

  class Test implements ClassInInterface {
    public void howdy() {
      System.out.println("Howdy!");
    }
  }
}

// Usage
ClassInInterface test = new Test();
test.howdy();

/* Output: Howdy!

*/// :~

It’s completely valid! Why would you want to do it that way? One valid reason is that if you wanted to have a common implementation of the interface. The downside is that the interface is “heavier” to carry around, but that’s probably very minor.

Multi nested inner classes

Back to the basic inner classes. Does a 2nd or 3rd level inner class have access to the layers above? Yes, it does, it has access to all layers. Thinking in Java has a great example, see below.

// Nested classes can access all members of all
// levels of the classes they are nested within.
class MNA {
  private void f() { }
  class A {
    private void g() { }
    public class B {
      void h() {
        g();
        f();
      }
    }
  }
}

public class MultiNestingAccess {
  public static void main(String[] args) {
    MNA mna = new MNA();
    MNA.A mnaa = mna.new A();
    MNA.A.B mnaab = mnaa.new B();
    mnaab.h();
  }
} // /:~

More to come…

I don’t like long tutorials nor long chapters. That’s why I’m breaking these into parts. When will it end? I have done 3 parts already and I’m not done! In Part 4, I’ll try to cover another advanced topic, Multiple Inheritance. Bruce Eckel has an interesting example.

Reference
Thinking in Java (4th), Bruce Eckel
Java Inner Classes – Part 1 – Intro
Java Inner Classes – Part 2 – Anonymous

Java Inner Classes – Part 2 – Anonymous

In Part 1, Java Inner Classes – Intro, I covered most of the basics of inner classes. But there is much more. Some of it might get complex and confusing. But with all of that, I am beginning to understand and value what Bruce Eckel tries to say when he introduces inner classes.

At first, inner classes look like a simple code-hiding mechanism: You place classes inside other classes. You’ll learn, however, that the inner class does more than that–it knows about and can communicate with the surrounding class–and the kind of code you can write with inner classes is more elegant and clear, although there’s certainly no guarantee of this.

Initially, inner classes may seem odd, and it will take some time to become comfortable using them in your designs. The need for inner classes isn’t always obvious, but after the basic syntax and semantics of inner classes have been described, the section “Why inner classes?” should begin to make clear the benefits of inner classes.

In part 2, I am going to cover even more obscure, but more advanced topics. I like to learn by example, this part is heavy on examples.

Local inner class

Did you know you can define a class within a method? Yes, you can. It’s called a local inner class. Example below.

// Nesting a class within a method.
// Example from Thinking in Java
public class Parcel5 {
  public Destination destination(String s) {
    class PDestination implements Destination {
      private String label;
      private PDestination(String whereTo) {
        label = whereTo;
      }
      public String readLabel() {
        return label;
      }
    }
    return new PDestination(s);
  }

  public static void main(String[] args) {
    Parcel5 p = new Parcel5();
    Destination d = p.destination("Tasmania");
  }
} // /:~

Class within a method

How about a class within an “if” statement. Yes, you can do that as well. It’s called a class within arbitrary scope, see below.

// Nesting a class within a scope.
// Thinking in Java example
public class Parcel6 {
  private void internalTracking(boolean b) {
    if (b) {
      class TrackingSlip {
        private String id;
        TrackingSlip(String s) {
          id = s;
        }
        String getSlip() {
          return id;
        }
      }
      TrackingSlip ts = new TrackingSlip("slip");
      String s = ts.getSlip();
    }
    // Can't use it here! Out of scope:
    // ! TrackingSlip ts = new TrackingSlip("x");
  }

  public void track() {
    internalTracking(true);
  }

  public static void main(String[] args) {
    Parcel6 p = new Parcel6();
    p.track();
  }
} // /:~

One other interesting part about the example above is that the class TrackingSlip will get compiled and a class file created. However, this class will only be accessible from within the scope it got created in.

Anonymous inner classes

Did you know you can return a class from inside the method body? A class that is not accessible from anywhere else. A class that has no name. Yes, that’s why it’s called anonymous. See example below.

// Returning an instance of an anonymous inner class.
// Thinking in Java example
public class Parcel7 {
  public Contents contents() {
    return new Contents() {
      // Insert a class definition
      private int i = 11;
      public int value() {
        return i;
      }
    }; Semicolon required in this case
  }

  public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Contents c = p.contents();
  }
} // /:~

Observe the syntax. The first statement in the method body is a return statement. It looks like you are returning a new instance of a class or interface. But that’s not it. You are actually creating/implementing the class, so you open a curly brackets { and close with }; and put the class definition inside. Very tricky and hard to get used to, I think.

Passing Arguments / Anonymous ConstructorWhat if you need to pass an argument and do some constructor initialization. It turns out you can.

// Creating a constructor for an anonymous inner class.
// Thinking in Java example
abstract class Base {
  public Base(int i) {
    print("Base constructor, i = " + i);
  }
  public abstract void f();
}

public class AnonymousConstructor {
  public static Base getBase(int i) {
    return new Base(i) {{
      print("Inside instance initializer");
    }
    public void f() {
      print("In anonymous f()");
    }};
  }
  public static void main(String[] args) {
    Base base = getBase(47);
    base.f();
  }
}
/** Output:
Base constructor, i = 47
Inside instance initializer
In anonymous
f()
*/// :~

One note about arguments. If you’re using them inside the inner class, they have to be passed as final. In the above case, it’s not used directly so a non-final argument is fine.

More: You can even define an instance variable in an inner class!

Here’s a snippet from Thinking in Java that illustrates that:

public Destination destination(final String dest, final float price) {
  return new Destination() {
    private int cost;
    // Instance initialization for each object:
    {cost = Math.round(price);
    if(cost > 100)
      System.out.println("Over budget!");
  }

  private String label = dest;
  public String readLabel() {
    return label;
  }};
}

Note that in the above example, because price was used in the inner class, it had to be defined as final.

Here’s a final note from Bruce about anonymous inner classes.

Anonymous inner classes are somewhat limited compared to regular inheritance, because they can either extend a class or implement an interface, but not both. And if you do implement an interface, you can only implement one.

More fun with inner classes to come! :) In Part 3, I’ll cover nested classes.

Reference
Thinking in Java (4th), Bruce Eckel
Java Inner Classes – Part 1 – Intro, The Pragmatic Craftsman

Java Inner Classes – Intro

I believe in writing self-documented, easy to read code. I believe in mantra that simple is beautiful Inner classes are not good tools for that task. I think they make the task of writing good code much harder: weird syntax, different rules, etc. Mostly for that reason, I have not really learned inner classes. I rarely use them. But whether you like inner classes or not, they are a fundamental feature of Java. You can find examples of inner classes in the Java collections. Map.Entry is one example.

Where am I going with this? I think inner classes come useful in some circumstances. You can develop some really complex features with them. And as a Java developer, you should know what’s in your toolbox. Sooner or later you will come across them. You might have to read code that uses them. Or you might utilize them to make your task easier.

Either way, it’s time to learn inner classes.

My goal here is to create a series of articles/tutorials on inner classes with a goal of learning them on a more deeper level. I came across some very good references on inner classes in Thinking Java book by Bruce Eckel. I’ll mostly use that book, plus some other references for this series.

Inner Classes

What’s an inner class? It’s a class defined within another class.

public class Outer {
  public class Inner {
    // inner fields, methods, etc
  }
}

Simple, right? That’s basically where it ends. Inner classes have more privileges than regular classes. There are different types of inner classes. Like I said, it’s a beast.

One nice thing about inner classes is that they allow you to group related classes together. Comes in handy at times.

Take a look at the example above one more time. How would you create an instance of Inner?

Inner inner = new Inner(); // not going to work

// how about -- seems like this should work
Inner = new Outer.Inner();

// getting closer, but still not there
// let's try to first create an instance of outer
// and then use that to create an instance of inner
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();

Yes! That will work. But look at the syntax! :-( Looks really weird to me. outer.new Inner() — but yes, that’s how you create an instance of inner.

One way to get around this weird syntax that Bruce Eckel uses is to create a method in outer that creates an instance of inner.

public class Outer {
  public class Inner {
    // inner fields, methods, etc
  }

  public Inner innerInstance() {
    return new Inner();
  }
}

// now you can use
Outer outer = new Outer();
Outer.Inner inner = outer.innerInstance();

I like that approach. Makes it much more readable.

Inner Class Features

So far, you’ve only seen how you would create an inner class. But what’s really different about an inner class?

    Inner class…

  • Has access to everything in the enclosing class (can access private variables and functions)
  • Can be private. You can’t do that with a regular class. If it is, only the outer class can instantiate it.

Here’s a good example from Thinking in Java:

// Holds a sequence of Objects.
interface Selector {
  boolean end();
  Object current();
  void next();
}

public class Sequence {
  private Object[] items;
  private int next = 0;

  public Sequence(int size) {
    items = new Object[size];
  }

  public void add(Object x) {
    if (next < items.length) items[next++] = x;
  }

  private class SequenceSelector implements Selector {
    private int i = 0;

    public boolean end() {
      return i == items.length;
    }

    public Object current() {
      return items[i];
    }

    public void next() {
      if (i < items.length)
        i++;
    }
  }

  public Selector selector() {
    return new SequenceSelector();
  }

  public static void main(String[] args) {
    Sequence sequence = new Sequence(10);
    for (int i = 0; i < 10; i++)
      sequence.add(Integer.toString(i));
      Selector selector = sequence.selector();
      while (!selector.end()) {
        System.out.print(selector.current() + " ");
        selector.next();
      }
    }
  }

/** Output: 0 1 2 3 4 5 6 7 8 9*/

Note that SequenceSelector is a private class, and how end(), current(), and next() access fields in the enclosed class. Pretty neat, actually.

Accessing Outer Instance

How would you access the outer object from within the inner? Guess what, another “tricky” syntax: Outer.this

public class SimpleOuter {
  private String name;
  private String getName() {
    return this.name;
  }

  private void setName(String name) {
    this.name = name;
  }

  public class Inner {
    public void accessOuter() {
      // note the SYNTAX
      SimpleOuter.this.setName("Test");
      System.out.println("Outer name: " + SimpleOuter.this.getName());
    }
  }

  public Inner inner() {
    return new Inner();
  }

  public static void main(String[] args) {
    SimpleOuter outer = new SimpleOuter();
    SimpleOuter.Inner inner = outer.inner();
    inner.accessOuter();
  }
}
/* Output:Outer name: Test*/

More…

You can’t create an instance of an inner class without creating an outer instance first and using that instance to create the inner. Well, there is, if the inner is static (called nested class). More to come in Part 2…

What makes a great software engineer?

Nicholas Zakas, the author of what I consider the best JavaScript book out there, is becoming one of my favorite bloggers! (I should let him know about that. :) ) In his recent blog post, he talks about qualities of great software developers. It’s a great post. I highly recommend reading the whole post.

Here’s my take on the qualities from the post.

Always do it the right wayI cannot agree more. There are always people that will say that they’ll improve it later; that this is special and it needs a special condition. It’s a big bull… You do it the right way ALL THE TIME. Really no exceptions.

Good engineers know that the right way applies to all situations and circumstances. If there’s not enough time to do something the right way, then there’s really not enough time to do it. Don’t make compromises, the quality of your work is what ultimately defines you as an engineer. Make sure that all of the code you write is done the right way 100% of the time. Expect excellence from yourself.

Be willing to sufferI never considered this as an asset before. On the contrary, I thought that it must be something wrong with me. I like to develop solutions in my head, thinking hard about them, then implementing. And later find a better solution. I rarely ask others for help. And I usually come up with good solutions. Hmm, maybe there’s hope in my software engineering skills. :-)

Great engineers first and foremost want to solve the problem on their own. Problem solving is a skill, a skill that great engineers take seriously.

Never stop learningIf you have been reading what I write on this blog, I don’t need to say anything else. This is an absolute must if you want to be considered a great software engineer.

In order to be a great engineer you must first admit that you don’t know everything, and then you must seek out more knowledge in every way you can.

Share your knowledgeI believe that’s what makes you valuable to the company you work for. That’s how you distinguish yourself from others. This is how you think “big picture”.

Great engineers want others to know what they know. They aren’t afraid of losing their position because someone else can do the same thing. Great engineers want to see their peers succeed and grow.

Lend a helping hand

Great engineers are team-focused and therefore are willing to do whatever it takes to help the team.

Do I need to argue with that?

Take your timeIt takes time to develop and improve on your skills. The only way to do that is by learning iteratively, practicing. It probably will take 5 to 10 years, or even more, for you to acquire great skills. To acquire that craftsman’s touch. :-)

ReferenceWhat makes a great software engineer?, Nicholas C. Zakas

Design Patterns Explained


Design Patterns Explained
by Alan Shalloway and James R. Trott
ISBN 0321247140
Date Read 8/2009

My Rating


Excellent intro to Design Patterns. I really liked the authors’ focus on teaching not only design patterns but how they should be used and implemented. Really good job there. I think this is a great book to start learning design patterns. If you want to learn DP, start with this book before you dive into the GoF Design Patterns book. Much to learn from this book, with a slow, more thorough way.

Not really a reference book. I tried to read this one quickly so I can get a quick refresher. This book is not suitable for that. Long explanations, not that much source code for examples. Yes, the explanations are good, but not if you want to quickly scan and refresh your memory. For that reason, I think the classic GoF book is still the king.

Overall, I appreciate the authors focus on teaching the right way of programming; trying to instill the “correct” thinking about patterns; and the detailed explanations of the different design patterns. I am disappointed that only a subset of patterns were explained and that this book is not suitable for reference. But all in all, a decent book.

Software Architecture Design Patterns in Java


Software Architecture Design Patterns in Java
by Partha Kuchana
ISBN 0849321425
Date Read 7/2009

My Rating


Good concept, bad implementation. After reading a few books on Design Patterns, I wanted to check out something else. Title of this book and decent reviews drew me in. I’m disappointed. After reading 20 chapters, I’m going to stop. I just don’t feel the author is doing a good job. There is not enough explanation on the different design patterns. The author gives a quick overview and then gives you an example. There is nothing wrong with that. But it’s very light. Each pattern is not explained enough. No benefits/drawbacks. No counter examples. Nothing really that will make the pattern “stick.” I just can’t learn anything from this book.

If you’re looking for a GoF book in Java, I would check out Design Patterns in Java or Design Patterns Explained. Not great, but I think they do a better job of explaining each pattern.

Learning Regular Expressions

I have to admit, my regex skills are not that sharp. I read a book on Regular Expressions before, but still, regex expressions just don’t stick in my mind. Too cryptic.

Can you read the following?

/^[a-z0-9_-]{3,16}$/

The following explanation might help.

DescriptionWe begin by telling the parser to find the beginning of the string (^), followed by any lowercase letter (a-z), number (0-9), an underscore, or a hyphen. Next, {3,16} makes sure that are at least 3 of those characters, but no more than 16. Finally, we want the end of the string ($).

String that matches: my-us3r_n4m3String that doesn’t match: wayt00_l0ngt0beausername (too long)

Clear, right? I love the description. It makes sense! This is an excerpt from an article 8 Regular Expressions You Should Know.

This one is a bit more complicated.

/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

DescriptionWe begin by telling the parser to find the beginning of the string (^). Inside the first group, we match one or more lowercase letters, numbers, underscores, dots, or hyphens. I have escaped the dot because a non-escaped dot means any character. Directly after that, there must be an at sign. Next is the domain name which must be: one or more lowercase letters, numbers, underscores, dots, or hyphens. Then another (escaped) dot, with the extension being two to six letters or dots. I have 2 to 6 because of the country specific TLD’s (.ny.us or .co.uk). Finally, we want the end of the string ($).

String that matches: john@doe.comString that doesn’t match: john@doe.something (TLD is too long)

Reference8 Regular Expressions You Should Know, nettuts (very good resource, btw)

Pro JavaScript Design Patterns


Pro JavaScript Design Patterns
by Ross Harmes, Dustin Diaz
ISBN 159059908X
Date Read 6/2009

My Rating


After reading a few books on JavaScript, I wondered… I wish there was a JavaScript book on Design Patterns. I was very glad when I found this book! It’s an advanced book loaded with great content, interesting style, and practical examples.

2 in 1. Not only do you get a refresher on Design Patterns, but you get to see some advanced JavaScript. It’s a really good combination.

Design Patterns/Javascript combination. This is a design patterns/JavaScript book. That said, you will not really learn JavaScript from it. Similarly, if you want to learn Design Patterns, you are better off going somewhere else. But if you combine these two, and don’t really focus on either one, you get a nice result. That’s exactly what this book is all about: how to implement some GoF patterns in JavaScript.

Design patterns. Which ones? Not all of them, but majority. Looking at the TOC, 12 GoF patterns are covered (Singleton, Factory, Bridge, Composite, Facade, Adapter, Decorator, Flyweight, Proxy, Observer, Command, and Chain of Responsibility). Plus the authors included chapters on Interfaces, Encapsulation, Information Hiding, Inheritance, and Chaining.

Best practices. The authors focus on creating best-practices solutions. I love that. I also love the authors style of code. You get to learn several different styles of creating JavaScript objects. (Could use a bit more explanation about them, but this is not an intro book.) I like to learn from examples, and there are plenty in this book.

Heavy on code examples. Light on explanation. I said it before, the way this book is written makes it suitable for you only if you have a good grasp of JavaScript and GoF Design Patterns. But still, I found this book hard to understand at times. I lost focus a few times. I think the authors could have done a much better job in this regard. The authors briefly explain the pattern and then they give you a long example. A short explanation follows. Very brief. If you don’t understand the full example, you’re out of luck. I would like to see short snippets extracted from the full example and explained. Repeated. So you learn better. And clearer that way.

Plan to re-read. You are most likely not going to “get” this book on your first read. I plan to re-read it. I will take it as an opportunity to deepen my GoF design patterns knowledge. Sort of read two books at once. Sounds like a plan. :)

I really liked this book. Design patterns knowledge is very relevant. JavaScript is gaining popularity and getting more advanced. It’s becoming a real programming language. I am still surprised how far it has come. This book is a really good gift to both communities. I highly recommend this book. It’s just the the book I was looking for!

DOM Scripting


DOM Scripting
by Jeremy Keith
ISBN 1-59059-533-5
Date Read 5/2009

My Rating


I believe in doing things the right way. So does the author of this book. In this regard, this is a great book: You learn what the right way is.

Not for hard-core developers. The intended audience is web designers. I second that. This book is also an excellent choice if you’re just thinking whether web-development with JavaScript is for you. Or if you want to read about web-development’s best practices (read chapter 5). It is not thorough and does not cover the advanced topics, like OO programming, etc.

Doing things right. And how to get there. This the nicest feature about this book. Slowly, sometimes first showing the bad approach and then refactoring to a more best-practices oriented solution. Nicely done. I wish more beginning books had an approach like this.

Separation of concerns: Separation of layers. My main objective for reading this book was so I learn more about the best practices. I did not learn anything new, but reading about the best practices again is a nice refresher. Separating structure, presentation, and behavior is the most important best practice when doing web development. The author does a good job explaining and really diving into this concept.

To say it once more, HTML, CSS, and JavaScript should be separate. You’ll learn that in this book.

Object-Oriented JavaScript


Object-Oriented JavaScript
by Stoyan Stefanov
ISBN 1847194141
Date Read 5/2009

My Rating


After reading my last JavaScript book, Professional JavaScript for Web Developers, I was looking for some more JS books to read. Something good. Then a few days ago I read a post by Klaus Komenda, Book Review: Object-Oriented JavaScript, and he highly recommended this book. (In the process, I also discovered DOM Scripting, and Pro JavaScript Design Patterns.) I picked up this book and had high expectations.

Decent book. After finishing the excellent Professional JavaScript for Web Developers book, the standards were set very high. This book is good, but not as deep, and not filled with as many full examples. It’s good, but not as good.

Quick. This book reads very quickly. The examples are short, the writing style is very conversational. That’s a nice feature. On the downside, sometimes a feature you’re reading is not easy and you’d like a bit more on the subject. You’re out of luck.

I learned a few things. Firebug console can execute JavaScript — I did not know that! I also got an overview of regular expressions syntax in JavaScript. Good job there. I also learned couple other things, but majority of the concepts in this book were included in the Pro book I mentioned.

Overall, not a bad book, but I don’t recommend it. By now, you know which JS book I do recommend. :-)

Favorite Quote

Topics

Tags

Archive

Currently Reading

Info

© 2001-2024 Stanley Kubasek About me :: Contact me

Me on Twitter

»see more

Recent Entries