Difference between revisions of "Inner Classes"

From Suhrid.net Wiki
Jump to navigationJump to search
Line 108: Line 108:
  
  
 +
<u> '''Anonymous Inner Classes''' </u>
 +
 +
* Perhaps the most popular of the inner classes.
 +
* Convenient for defining classes on the spot. Used a lot in Swing, Threads.
 +
* See example below. We need to create a new thread just in a method. Instead of defining a separate thread class, implementing runnable etc. We can do the following:
 +
 +
<syntaxhighlight lang="java5">
 +
 +
public void foo() {
 +
             
 +
                Thread t1 = new Thread(new Runnable() {
 +
                       
 +
                        void go() {
 +
 +
                        }
 +
 +
public void run() {
 +
System.out.println("HerpDerp");
 +
}
 +
});
 +
 +
t.start();
 +
               
 +
                //Note: t1.go() will not work. Since methods can be invoked based on the reference type only. i.e. what is defined in Thread.
 +
                //Even shorter
 +
               
 +
}
 +
 +
</syntaxhighlight>
  
 
[[Category:OCPJP]]
 
[[Category:OCPJP]]

Revision as of 01:42, 7 June 2011

  • Inner classes have access to members of the outside classes.
  • Think of the Inner class as sort of a MEMBER of the outer class.

Regular inner classes

  • This means that regular Inner classes cannot have any statics (variables or methods)
  • Only way to access an instance of the inner classes is through an instance of the outer class.
  • Remember the funny syntax:
class Outer {
  class Inner() {

  }
}

Outer o = new Outer();
Outer.Inner i =  o.new Inner()
  • There are different ways on how regular inner class instances can be created, depending on where it is accessed from. See below:
class Outer {
	private String s = "";
	
	Outer() {
		
	}
	
	Outer(String s) {
		this.s = s;
	}
	
	public String toString() {
		return s;
	}
	
	class Inner {
		private String s = "";
		
		Inner() {
			
		}
		
		Inner(String s) {
			this.s  = s;
		}
		
		public String toString() {
			return s;
		}
		
		void in() {
			System.out.println("Inner object : " + this);       //The inner objects instance
			System.out.println("Outer object : " + Outer.this); //Access the outer object's instance
		}
		
		void makeInner() {
			Inner i = new Inner(); //Within the inner class, so regular way to access.
		}
	}
	
	private void makeInner() {
		Outer o = new Outer();        //Accessing from within the outer class
		Inner i = o. new Inner();     //Class name can be used as-is
	}
	
}

public class TestInner {
	
	public static void main(String[] args) {
		Outer o1 = new Outer("o1");              //Accessing from outside the outerclass
		Outer.Inner o1i1 = o1.new Inner("o1i1"); //Class name has to be Outer.Inner 
		o1i1.in();
	}
	
}


Method Local Inner Classes

  • Class defined inside a method
  • Class can ONLY be instantiated from within the method where it is declared, not anywhere else.
  • The class cannot use the local variables of the method, including the method arguments unless the variables are declared as final.
  • Why ? The class object can continue to live on the heap, till it's GC'ed even after the method is popped off from the stack, so trying to accessing method local variables after they are destroyed will be disastrous.
  • By making the variables final, this is in effect turning them into constants. So the compiler can replace the variables with actual values, thus eliminating the problem of the inner class accessing destroyed variables.


private void foo(final int x) {
		
		String str = "hello";
		
		class InnerFoo {
			public void go() {
				System.out.println("x is : " + x); //This is OK, because x is marked as final.
				// System.out.println(str); //This won't work because str is not final.
			}
		}
		
}


Anonymous Inner Classes

  • Perhaps the most popular of the inner classes.
  • Convenient for defining classes on the spot. Used a lot in Swing, Threads.
  • See example below. We need to create a new thread just in a method. Instead of defining a separate thread class, implementing runnable etc. We can do the following:
public void foo() {
               
                Thread t1 = new Thread(new Runnable() {
                        
                        void go() {

                        }			

			public void run() {
				System.out.println("HerpDerp");
			}
		});
		
		t.start();
                
                //Note: t1.go() will not work. Since methods can be invoked based on the reference type only. i.e. what is defined in Thread.
                //Even shorter
                
}