Java 为什么可以';我不能直接访问singleton实例吗?
例如:Java 为什么可以';我不能直接访问singleton实例吗?,java,singleton,Java,Singleton,例如: 公共类单例{ 私有静态最终单例实例=新单例(); //私有构造函数抑制 //默认公共构造函数 私有单态(){}; 公共静态单例getInstance(){ 返回实例; } } 为什么我不能将实例设置为public,并通过Singleton.INSTANCE访问它?它会导致什么?从技术上讲,您可以这样做,但在本代码中,它不会产生任何影响-它的行为将是相同的 我们通常使用getter的原因是: 一个好习惯——人们会惊讶地看到您直接访问变量 灵活性—如果在调用getter的代码中有100个
公共类单例{
私有静态最终单例实例=新单例();
//私有构造函数抑制
//默认公共构造函数
私有单态(){};
公共静态单例getInstance(){
返回实例;
}
}
为什么我不能将
实例设置为public,并通过Singleton.INSTANCE
访问它?它会导致什么?从技术上讲,您可以这样做,但在本代码中,它不会产生任何影响-它的行为将是相同的
我们通常使用getter的原因是:
- 一个好习惯——人们会惊讶地看到您直接访问变量
- 灵活性—如果在调用getter的代码中有100个位置,那么很容易更改方法行为(比如每次都返回
new Singleton()
,而不是访问静态变量)。如果这一百个地方直接访问变量,就不那么容易了
从技术上讲,您可以将Singleton.INSTANCE
公开,因为它是最终版
。但是,从API用户的角度来看,Singleton.INSTANCE
在不查看Singleton
类的内容的情况下是最终的,这一点并不明显,用户可能会尝试从其他类重新分配Singleton.INSTANCE
使Singleton.INSTANCE
只能通过Singleton.getInstance()访问
使每个人都清楚地认识到,不可能重新分配变量。因为封装实例是一种良好的做法,以避免使用锅炉板代码,在这种情况下,您需要使用静态块来初始化对象,如果在需要时初始化对象(延迟加载),效果会更好可能对内存使用有好处。因为您尝试访问的实例变量是私有的。使用getInstance()方法,因为它是公共的。这将阻止您更改getInstance()
的实现,以将单例的实例化推迟到第一次需要时(如果您选择的话)。将访问封装在方法中使将来的更改更容易。@gnanajeyam95您读过这个问题了吗?OP知道它是私有的
,并询问将其更改为公共的
是否会引起任何问题。从本质上讲,将其设置为公共的
。与没有setter方法相比,最终的
如何不那么明显?查看Singleton.getInstance()
与查看Singleton.INSTANCE
关于能够更改实例的可能性没有什么区别。@Andreas这不太明显,因为它需要读取Singleton
类的内容,除非您有一个高级IDE。这不是有点牵强吗?使用Singleton.getInstance()
时,由于getter/setter模式,用户可能认为可以使用Singleton.setInstance(instance)
方法对其进行更改。如果他们尝试了,他们会发现setInstance
不存在。这与tring赋值给Singleton.INSTANCE
,然后发现编译器拒绝了,因为字段是final
@NathanielJones,但它还需要读取Singleton类的内容,以确定没有setter方法。有了IDE,两者都很容易检查,因此同样明显。在没有IDE的情况下,定位字段并检查final
修饰符既简单又快速,因为一旦找到字段(通常在开头),就可以停止扫描仪。检测是否缺少setter方法需要扫描整个源文件,因此检查字段是否为final肯定比检查setter方法是否存在更明显(更容易、更快)。@NathanielJones另外,如果字段不是final
,即使它是private
,也可以通过setter方法以外的代码进行更改,这意味着您需要扫描源文件中的所有代码,而不仅仅是方法签名,因此即使是IDE也无法加快速度。final
字段总是比缺少setter方法更明显。