说明:本文是我对自己学习知识的一个简单总结,可能存在许多不足,我希望通过此方式来回顾知识,加强理解,也希望大家能指出文中的错误与不足,互相学习,谢谢。
内部类是什么
- 内部类就是在类中的类,当然也可以写在方法中,称为局部内部类。那为什么需要内部类呢?
内部类可以调用外部类的私有属性和私有方法。
内部类使得开发更加可读,代码维护有针对性。
内部类可以对同一包中的其他类隐藏起来。
内部类可以解决 java 单继承的缺陷。
- 这里我主要分析下内部类是怎样访问外部类属性和方法的,我们来看一下列子
1.普通内部类
public class OutClass {
public String outStr;
public OutClass(String outStr){
this.outStr = outStr;
}
class innerClass{
public void innerMethod(){
System.out.println(outStr);
}
}
public static void main(String[] args) {
}
}
- 上面是一个内部类访问外部类私有方法的例子,我们先通过javac OutClass.java编译源文件,编译成功后生成OutClass.class和OutClass i n n e r C l a s s . c l a s s 字 节 码 文 件 , 然 后 通 过 j a v a p − v e r b o s e O u t C l a s s innerClass.class字节码文件,然后通过javap -verbose OutClass innerClass.class字节码文件,然后通过javap−verboseOutClassinnerClass.class查看字节码文件,截取如下部分:
- 所以在编译阶段,内部类通过默认构造方法将外部类传入,这样就可以访问外部类的属性和方法了。
那么怎样调用内部类中的方法呢?看下面的代码
public class OutClass {
public String outStr = "123";
class InnerClass{
public void innerMethod(){
System.out.println(outStr);
}
}
public static void main(String[] args) {
OutClass outClass = new OutClass();
InnerClass innerClass = outClass.new InnerClass();
innerClass.innerMethod();
}
}
- 可以看到通过外部类对象.new InnerClass()创建内部类对象,这样就可以调用内部类方法了,因为内部类可以看作外部类的一个特殊属性,通过OutClass对象的实例去访问对象的属性。
2.静态内部类
静态内部类是由static关键字修饰的类。它可以独立存在,静态内部类只能访问外部类的静态属性和方法。
public class OutClass {
public static String outStr = "123";
static class InnerClass{
public void show() {
System.out.println(outStr);
}
}
public static void main(String[] args) {
new OutClass.InnerClass().show();
}
}
3.匿名内部类
匿名内部类也就是没有名字的内部类
interface InnerClass{
void show();
}
public class OutClass {
public String outStr = "123";
public void show(){
new InnerClass(){
@Override
public void show() {
System.out.println(outStr);
}
}.show();
}
public static void main(String[] args) {
OutClass outClass = new OutClass();
outClass.show();
}
}
- 通过javac OutClass.java后可以看到产生了OutClass.class OutClass$1.class InnerClass.class三个class字节码文件,反编译OutClass$1.class(javap -verbose OutClass$1)得到如下结果
- 从上图可知,OutClass$1就是匿名内部类编译后的默认名称,还可以看出匿名内部类需要实现一个接口。