java内部类为什么可以访问外部类属性方法

java内部类面试题:

java内部类分类:

成员内部类,局部内部类,静态内部类,匿名内部类

静态内部类不能访问外部类的属性方法,所以android开发过程中可以优化handler

其他内部类可以访问外部类,是因为持有外部类的引用。

成员内部类说明:

成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,默认情况下访问的是成员内部类的方法。访问外部类方法:

外部类.this.成员变量

外部类.this.成员方法

外部类想访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问,内部类的创建依赖外部类:

        Outter outter = new Outter();

        Outter.Inner inner = outter.new Inner();  

  和外部类不同内部类可以用private,protected,public修饰,内部类有点类似外部类变量的味道。public 都可以访问,private修饰时只能在外部类的内部访问,protected修饰只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。

局部内部类:

方法内部定义,作用于在方法内部,不能用访问修饰符修饰。

匿名内部类,没有构造函数,主要用于事件绑定,回调函数设置。

静态内部类,添加了static 关键字,不依赖与外部类。

内部原理说明:

public class OuterClass {
	
	public static void main(String args) {
		
	}

	class Inner1 {
		
	}
	
	static class Inner2{
		
	}
	
	public  void getInner() {
		class Inner3{
			
		}
	}
	
	public  void getEvent() {
		setClick(new Event() {

			@Override
			public void onClick() {
				
			}
			
		});
	}
	
	interface Event{
		void onClick();
	}
	
	public void setClick(Event event) {}
	
}

编译之后生成:

java内部类为什么可以访问外部类属性方法_第1张图片

利用javap -p 命令进行分析。

OuterClass.class是外部类对应的class。

OuterClass$1是匿名内部类实现了接口Event的class

javap -p OuterClass$1.class

Compiled from "OuterClass.java"
class com.ldx.demo2.OuterClass$1 implements com.ldx.demo2.OuterClass$Event {
  final com.ldx.demo2.OuterClass this$0;
  com.ldx.demo2.OuterClass$1(com.ldx.demo2.OuterClass);
  public void onClick();
}

OuterClass$Inner1.class

javap -p OuterClass$Inner1.class
Compiled from "OuterClass.java"
class com.ldx.demo2.OuterClass$Inner1 {
  final com.ldx.demo2.OuterClass this$0;
  com.ldx.demo2.OuterClass$Inner1(com.ldx.demo2.OuterClass);
}

可以看到构造函数中持有外部类的引用,所以可以访问外部类。

OuterClass$Inner2.class

javap -p OuterClass$Inner2.class
Compiled from "OuterClass.java"
class com.ldx.demo2.OuterClass$Inner2 {
  com.ldx.demo2.OuterClass$Inner2();
}

静态内部类没有持有外部类的引用。

OuterClass$1Inner3.class

javap -p OuterClass$1Inner3.class
Compiled from "OuterClass.java"
class com.ldx.demo2.OuterClass$1Inner3 {
  final com.ldx.demo2.OuterClass this$0;
  com.ldx.demo2.OuterClass$1Inner3(com.ldx.demo2.OuterClass);
}

局部内部类持有外部类的应用

你可能感兴趣的:(java基础,java面试小问题)