- public class UserServiceFactory {
- public static UserServiceFactory getInstance() {
- return InnerHolder.instance;
- }
-
- private static class InnerHolder {
- private static final UserServiceFactory instance = new UserServiceFactory();
- }
- }
为什么能访问到内部静态类的私有属性呢?不是私有属性对外部类不可见的吗?
-
1 票
这个问题涉及到外部类和内部类的一个访问的性质:外部类和内部类都可以互相访问对方的任何成员,包括私有成员。所以问题中的代码是可以编译通过并且正常运行的。
下面解释原因。
编译上述代码,会发现生成了两个.class文件:UserServiceFactory.class和UserServiceFactory$InnerHolder.class,说明内部类和外部类是分开编译的,都是作为单独的类进行操作的。然后对生成的UserServiceFactory.class文件进行反编译,函数getInstance()的结果如下:
- public static UserServiceFactory getInstance()
- {
- return InnerHolder.access._mth1(new InnerHolder(null));
- }
注意,这里函数里面变成了返回InnerHolder.accsee._mth1(new InnerHolder(null)),而并不是最原始的样子。这就是秘诀所在了。对于内部类,编译器会对private成员都生成一个函数,一般都是以access开头。而对于外部类对内部类的private成员的访问,编译器更改为对这个内部类的对应函数的调用,从而实现了对内部类private成员的访问。
而对于通过new InnerHolder(null)来创建内部类对象,是因为编译器给内部类添加了一个额外的包访问权限的构造器,如下所示:
- UserServiceFactory$InnerHolder(UserServiceFactory$InnerHolder userservicefactory$innerholder)
- {
- this();
- }
其中this()是调用内部类自己的私有构造函数。外部类能够访问到这个包访问权限构造器,所以能够构造内部类对象,并调用相关方法。
推荐一篇文章,LZ可以去看看。Java内部类