java 内部类
一.java内部类:
java内部类分为:
成员内部类、静态嵌套类、方法内部类、匿名内部类 。
内部类的共性:
(1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。
二.内部类语法:
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所修饰的值始终无法改变,所以这个变量所指向的内存区域就不会变。