内部类中的变量访问
java的内部类主要分为,普通内部类,静态内部类,局部内部类,匿名内部类。内部类中变量的访问,主要由以下几点:
- 内部类可以访问主类中的任何变量,包括私有的变量。但是如果是静态内部类就只能访问主类中的静态变量,不能访问主类中的非静态变量。
- 对于局部内部类来说,如果里面的参数变量不会发生任何改变,在jdk8中即使不用final关键字修饰,编译器也不会报错,也就是说局部内部类只能使用final修饰的变量
具体的示例如下:
/**
* All rights reserved.
* Created by zhaideyin on 2017/10/26.
* Description:
*/
public class InnerClass {
public InnerClass(String name){
System.out.println(name);
}
public String name="I am out";
public static String ststicName="I am static variable " ;
private static String privateName="I am private variable " ;
//静态内部类
public static class InnerClassA{
void showA(String A_name){
System.out.println("静态内部类");
// System.out.println("InnerClassA"+name);添加这一行编译器会报错,静态内部类不能访问主类的非静态变量
System.out.println(" InnerClassA:"+ststicName);//静态内部类能够访问主类的公共变量
System.out.println(" InnerClassA:"+privateName);//静态内部类能够访问主类的私有变量
}
}
//普通内部类
class InnerClassB extends BaseClass{
void showB(){
System.out.println("普通内部类");
System.out.println("InnerClassB:"+name);//普通内部类能够访问主类的公共变量
System.out.println("InnerClassB:"+ststicName);//普通内部类能够访问主类的静态变量
System.out.println("InnerClassB:"+privateName);//普通内部类能够访问主类的私有变量
}
}
public void show(){
int a=10;
//局部内部类
/*private*/ class InnerClassC{//局部内部类不能有访问修饰符,任何的访问修饰符都会报错
void showC(){
//a=29;局部内部类的访问的局部变量必须为final类型,在jdk8中,int a=10;的声明并不会报错,只要不修改a的值。jdk8以下会报错
System.out.println("局部内部类");
System.out.println("InnerClassC:"+name);//局部内部类可以访问主类的普通变量
System.out.println("InnerClassC:"+ststicName);//局部内部类可以访问主类的静态变量
System.out.println("InnerClassC:"+privateName);//局部内部类可以访问主类的私有变量
}
}
}
public BaseClass getInnerClass(){
int a=10;
final int b=20;
//匿名内部类,如果匿名内部类内部的方法需要修改形参的话,则该参数只能声明为final类型,否则编译器会报错 jdk8以下的必须用final修饰,
return new BaseClass(){
public void show() {
//a=90;
System.out.println(a);
System.out.println("匿名内部类");
System.out.println("InnerClassD:"+name);//匿名内部类可以访问主类的普通变量
System.out.println("InnerClassD:"+ststicName);//匿名内部类可以访问主类的静态变量
System.out.println("InnerClassD:"+privateName);//匿名内部类可以访问主类的私有变量
}
int test(){
// a=30;//编译器会报错,默认引用的参数必须是final类型的,否则编译器会报错
return a+b;
}
};
}
public static void main(String[] args) {
InnerClass innerClass=new InnerClass("mainClass");
// InnerClassB innerClassB1=new InnerClassB();该行代码会报错,普通内部类的实现是必须依赖于外部类的实现
InnerClass.InnerClassB innerClassB=innerClass.new InnerClassB();
InnerClassA innerClassA=new InnerClassA();//静态内部类的实现并不依赖外部类的实现
//对于匿名内部类的获取通常是通过方法来获取的
BaseClass baseClass= innerClass.getInnerClass();
}
}
class BaseClass{
void show(){};
}
这里解释以下为什么局部内部类所使用的变量都必须用final 修饰:
匿名内部类,如果匿名内部类内部的方法需要修改形参的话,则该参数只能声明为final类型,否则编译器会报错 jdk8以下的必须用final修饰,
主要是java在调用方法的时候,会在方法栈中为局部变量分配内存空间,方法调用结束后局部变量就得销毁, 可是局部内部类的是分配在堆中的,它的生命周期并不会随着方法的结局而结束,所以局部内部了访问和使用到的局部变量就不能随着方法的消亡而消亡,因此局部内部类的 变量就必须声明为final类型
谈一下个人对于java内部类的理解:
java的内部类的引入,根据java 编程思想上面的说法是为了让继承体系更加完整,内部类可以独立于主类之外去继承一个父类或者是接口,并且不受主类的影响,并且表现出不同的结构。除此之外,内部类也是实现代码隐藏的另一种非常好的方式,当然内部类能够灵活的于外部类进行通信。