java 内部类
一.java内部类:
java内部类分为:
成员内部类、静态嵌套类、方法内部类、匿名内部类 。
内部类的共性:
1.成员内部类:
1 package com.main; 2 3 /** 4 * 5 * @author PC 6 * 7 */ 8 public class Test { 9 10 /** 11 * 12 */ 13 public Test() { 14 // TODO Auto-generated constructor stub 15 } 16 17 /** 18 * @param args 19 */ 20 public static void main(String[] args) { 21 // TODO Auto-generated method stub 22 23 // 成员内部类 24 A a = new A(); 25 a.getName(); 26 27 //没有get方法,就用此方法创建内部类 28 // A.A1 a0=a.new A1(); 29 // a0.getName(); 30 31 // 通过get获取内部类对象 32 A.A1 a1=a.get(); 33 a1.getName(); 34 } 35 } 36 37 class A { 38 final String name = "张三"; 39 // 个人推荐使用get()来获取成员内部类,尤其是该内部类的构造函数无参数时 40 public A1 get() { 41 return new A1(); 42 } 43 44 public class A1 { 45 public void getName() { 46 System.out.println("A1:"+name); 47 } 48 } 49 50 public void getName() { 51 System.out.println("A:"+name); 52 } 53 }
2.静态嵌套类:
1 package com.main; 2 3 /** 4 * 5 * @author PC 6 * 7 */ 8 public class Test { 9 10 /** 11 * 12 */ 13 public Test() { 14 // TODO Auto-generated constructor stub 15 } 16 17 /** 18 * @param args 19 */ 20 public static void main(String[] args) { 21 // TODO Auto-generated method stub 22 23 //E.E1 e1=new E.E1(); 24 //e1.getName(); 25 26 E.E1.getName1(); 27 28 } 29 30 31 } 32 33 class E{ 34 static String name = "张三"; 35 static class E1{ 36 public void getName(){ 37 System.out.println(name); 38 } 39 public static void getName1(){ 40 System.out.println(name); 41 } 42 } 43 }
3.方法内部类:
1 package com.main; 2 3 /** 4 * 5 * @author PC 6 * 7 */ 8 public class Test { 9 10 /** 11 * 12 */ 13 public Test() { 14 // TODO Auto-generated constructor stub 15 } 16 17 /** 18 * @param args 19 */ 20 public static void main(String[] args) { 21 // TODO Auto-generated method stub 22 23 // 方法中内部类 24 B b=new B(); 25 b.getName(); 26 } 27 } 28 29 class B { 30 final String name = "张三"; 31 32 public void getName() { 33 System.out.println("out:" + name); 34 class B1 { 35 public void getName() { 36 System.out.println("in:" + name); 37 } 38 } 39 B1 b1 = new B1(); 40 b1.getName(); 41 } 42 }
4.匿名类:
A:继承式:
1 package com.main; 2 3 /** 4 * 5 * @author PC 6 * 7 */ 8 public class Test { 9 10 /** 11 * 12 */ 13 public Test() { 14 // TODO Auto-generated constructor stub 15 } 16 17 /** 18 * @param args 19 */ 20 public static void main(String[] args) { 21 // TODO Auto-generated method stub 22 23 //匿名内部类 24 C c=new C(){ 25 public void getName(){ 26 System.out.println("c"+name); 27 } 28 }; 29 c.getName(); 30 31 } 32 } 33 34 35 class C{ 36 String name = "张三"; 37 public void getName(){ 38 System.out.println(name); 39 } 40 }
B:接口式:
1 package com.main; 2 3 /** 4 * 5 * @author PC 6 * 7 */ 8 public class Test { 9 10 /** 11 * 12 */ 13 public Test() { 14 // TODO Auto-generated constructor stub 15 } 16 17 /** 18 * @param args 19 */ 20 public static void main(String[] args) { 21 // TODO Auto-generated method stub 22 23 D d=new D(){ 24 public void getName(){ 25 System.out.println(name); 26 } 27 }; 28 d.getName(); 29 } 30 } 31 32 33 interface D{ 34 String name = "张三"; 35 public void getName(); 36 }
三.外部类变量为什么要使用final:
因为生命周期的原因。方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。
首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候,这个局部变量肯定也就被GC了,然而内部类的某个方法还没有执行完,这个时候他所引用的外部变量已经找不到了。如果定义为final,java会将这个变量复制一份作为成员变量内置于内部类中,这样的话,由于final所修饰的值始终无法改变,所以这个变量所指向的内存区域就不会变。