class A{
private static int i;
//内部类
class B
{
private int k=333;
B(){i=8;}//修改外部类的i
}
public void f(){
B bb=new B();
}
public static void main(String[] args){
A aa=new A();
aa.f();
System.out.println(i);
System.out.println(new A().new B().k); //这里怎么可以直接访问内部类数据成员,这不破坏了封装了吗??
}
}
private static int i;
//内部类
class B
{
private int k=333;
B(){i=8;}//修改外部类的i
}
public void f(){
B bb=new B();
}
public static void main(String[] args){
A aa=new A();
aa.f();
System.out.println(i);
System.out.println(new A().new B().k); //这里怎么可以直接访问内部类数据成员,这不破坏了封装了吗??
}
}
new A之后返回一个A的对象,A的对象当然能访问类A中的非私有性质的任何东西了。。
B在类A中是default属性的,所以A的对象当然能够去利用它再进行构造B的对象!至于后面的.k就不用我说了吧?
public class A { public static class B {
private int i = 333;
} public static void main(String[] args) {
int n = 0;
B t = new B();
n = t.i;
}}javap 结果:
javap -c -private A
Compiled from "A.java"
public class A extends java.lang.Object{
public A();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: new #2; //class A$B
5: dup
6: invokespecial #3; //Method A$B."<init>":()V
9: astore_2
10: aload_2
11: invokestatic #4; //Method A$B.access$000:(LA$B;)I //调用 B 的静态方法 access$000
14: istore_1
15: return}javap -c -private A$B
Compiled from "A.java"
public class A$B extends java.lang.Object{
private int i;public A$B();
Code:
0: aload_0
1: invokespecial #2; //Method java/lang/Object."<init>":()V
4: aload_0
5: sipush 333
8: putfield #1; //Field i:I
11: returnstatic int access$000(A$B); //编译器添加的静态方法,用于访问参数传入的内部类 B 对象的私有实例域 i 的值
Code:
0: aload_0
1: getfield #1; //Field i:I
4: ireturn}请注意类 A 的内部类 B,看似只有一个私有实例域 i,但实际上为了使 main 方法中能访问到 i 的值编译器又动了手脚,它给你加了个方法,使代码变成了下面这个样子:public class A { public static class B {
private int i = 333;
static int access$000(A$B t) { return t.i; } //编译器加上的
} public static void main(String[] args) {
int n = 0;
B t = new B();
n = B.access$000(t); //编译器改造后的 n = t.i;
}}这就是“破坏封装”的原因。
是什么东东啊??
我喜欢在基础上做到彻底理解.谢谢大家的理解
可以得到class文件的字节码指令表示。