简体   繁体   English

为什么使用私有修饰符用于不可变的最终实例var?

[英]Why use private modifier for immutable final instance var?

I'm writing a Java class representing some simple geometry. 我正在编写一个代表一些简单几何的Java类。

At the top-most abstract class (which itself is package-private ) I have declared attributes that I need be accessed from subclasses in the same package. 在最顶层的abstract类(它本身就是包私有 )中,我声明了需要从同一个包中的子类访问的属性。

If I declare an attribute as final in the AbstractClass , 如果我在AbstractClass声明一个属性为final

final int foo;

I'll able to access it in the package directly, without any fuss of a getter method. 我可以直接在包中访问它,而不用任何getter方法。 However. 然而。 Doing according to "praxis" (or what I believe is the common style) would be: 根据“praxis”(或我认为是常见的风格)做的将是:

private final int foo;

which would of course require a non- private getter. 这当然需要非private吸气剂。 The subclasses would have to refer to foo (which is a very relevant and quintessential attribute) as if it were some external object: 子类必须引用foo (这是一个非常相关和典型的属性),好像它是一些外部对象:

this.getFoo();

It adds code and removes the direct way of accessing these members (ie foo ). 它添加了代码并删除了访问这些成员的直接方式(即foo )。

Are there any disadvantages of skipping the private modifier, since they're anyway final and I'm not worried of exposing these attributes internally in the package? 跳过private修饰符是否有任何缺点,因为它们无论如何都是最终的,我不担心在包内部暴露这些属性?

I'm aware of OO-advocates claiming that getters/setters is a very natural way for objects to access their own attributes - but when does this make any non-cosmetic, non-[insert any JavaBeans-style thing], difference? 我知道OO倡导者声称getter / setter是对象访问他们自己的属性的一种非常自然的方式 - 但是什么时候这会使任何非整形,非[插入任何JavaBeans风格的东西],差异?

Consider an inner class, Coordinate , which is so simple because it has two int attributes - leaving all usage for class OuterClass : 考虑一个内部类Coordinate ,它非常简单,因为它有两个int属性 - 留下类OuterClass所有用法:

class OuterClass{
    final static class Coordinate{
        final int x, y;
        Coordinate(int x, int y){
            this.x = x;
            this.y = y;
        }
    }
    Coordinate coordinate;
}

For this inner class - why would I bother with the praxis of creating a getter? 对于这个内部阶级 - 为什么我要为创造一个吸气剂的实践而烦恼? A getter would introduce more code and force any class in the same package to call coordinate.getX(); getter会引入更多代码并强制同一个包中的任何类调用coordinate.getX(); instead of simply coordinate.x; 而不是简单的coordinate.x; . Any overhead here? 这有任何开销吗? Notice the final modifier on the class Coordinate . 注意Coordinate类的final修饰符。

The advantage of getters is decoupling interface from implementation. getter的优点是将接口与实现分离。 Today your getFoo might do nothing but return foo , but in the future you might want, for example, to remote the foo member and return a computed result instead. 今天你的getFoo可能getFoo返回foo ,但是将来你可能想要远程getFoo foo成员并返回计算结果。 A getter will allow you to do that without requiring a change at each call site. 获取者将允许您在不需要在每个呼叫站点进行更改的情况下执行此操作。

If you are ever going to access this value from JSF Page, it will expect getFoo rather than just foo (even if you write object.foo ). 如果你要从JSF页面访问这个值,它会期望getFoo而不仅仅是foo(即使你写了object.foo )。

Apart from that- today this field is final, long time from now it can change (I guess). 除此之外 - 今天这个领域是最终的,很长一段时间它可以改变(我猜)。 Even if the chance is very close to 0, I believe that there is no overkill in following good practices. 即使机会非常接近0,我相信在遵循良好做法方面也没有过度杀伤力。 Vast majority of the time you are making changes than writing code from scratch, so it is much better to safeguard yourself whenever possible (if all it takes is writing private and in case of eclipse about 4 clicks to generate the getter and setter automaticaly). 大多数时候你进行更改而不是从头开始编写代码,因此最好尽可能保护自己(如果只需编写private并且在eclipse的情况下大约需要4次点击以自动生成getter和setter)。

To extend Feldgendler's answer (with information which may be useful for someone needing the answer of this question --- I believe this is relevant because it is really a question about encapsulation): 扩展Feldgendler的答案(对于需要回答这个问题的人可能有用的信息 - 我相信这是相关的,因为它确实是一个关于封装的问题):

In effect of using private modifiers you will have to create the "getter" (eg int getX(){ ... } ) to sustain access. 在使用private修饰符时,您必须创建“getter”(例如int getX(){ ... } )以维持访问。 Which can be declared in an implemented interface . 哪个可以在已实现的interface声明。 A Java interface does not allow declaration of instance variables, such as the example of final int x; 一个Java interface 不允许实例变量,如该示例的声明final int x; --- or of any other variable lacking the static modifier. ---或缺少static修饰符的任何其他变量。 The interface will act as a declaration of the behavior any implementing class will have. 该接口将充当任何实现类将具有的行为的声明。

If implemented like: 如果实施如下:

Coordinate implements ICoordinate { ... }

it could be useful in many scenarios: 它在许多场景中都很有用:

The use of an interface 使用界面

  • Self-documentation of an API. API的自我记录。
    • Easy to read, document and manage. 易于阅读,记录和管理。
    • Hence, allowing several implementations to be readily used and swapped. 因此,允许容易地使用和交换多个实现。
    • In component-based design and more: provide explicit means to provide or require described behavior without actually having any implementation code ready. 在基于组件的设计中以及更多:提供显式方法来提供要求所描述的行为,而无需实际准备任何实现代码。
      • Example: One could then create a database component that provides an interface. 示例:然后可以创建一个提供接口的数据库组件。 John Doe wants to write a program that will in the future use a database. John Doe想要编写一个将来会使用数据库的程序。 For now however it is sufficient to use some other simpler form of storage. 但是现在使用其他更简单的存储形式就足够了。 In order not to re-code what is already working code when the day comes John could implement an interface (maybe given the name interface IDatabase ) with the methods void insert( ... ); Object get( ... ); 为了在日期到来时不重新编码已经正在运行的代码,John可以使用void insert( ... ); Object get( ... );方法实现一个接口(可能是名称interface IDatabase void insert( ... ); Object get( ... ); void insert( ... ); Object get( ... ); and perhaps a few more -- then implement his temporary solution. 或许还有一些 - 然后实施他的临时解决方案。 The day comes and he now has a database implementing the same interface IDatabase . 这一天来了,他现在有一个实现相同interface IDatabase的数据库。 To swap to the new database he might only need to change *one line of code* (eg the constructor call)! 要交换到新数据库,他可能只需要更改*一行代码*(例如构造函数调用)!
  • An example for the sake of it: http://pastebin.com/vvV2Nck8 一个例子是为了它: http//pastebin.com/vvV2Nck8

Using private modifier 使用私有修饰符

  • It Clarifies the intent of the class! 澄清了课程的意图 Much like the interface, it has the nature of being self-documenting. 与界面非常相似,它具有自我记录的性质。 (It has no value in security) (它没有安全价值)
    • private modifier would imply that it is NOT to be accessed out of scope. private修饰符意味着它不会超出范围。 Or equivalently -- only to be accessed within a certain scope. 或者等效 - 仅在特定范围内访问。 Same of course applies to public , "package-private" (no modifier implies package-private) and protected . 同样适用于public ,“package-private”(没有修饰符暗示package-private)和protected
    • Accessing an attribute will not explicitly tell the caller what kind of variable it is. 访问属性不会明确告诉调用者它是什么类型的变量。 Having a getter but no setter says something else however... 有一个吸气剂,但没有setter说了别的东西......
    • NOTE: For constants (eg static final double LIGHT_SPEED ) there is reasonable reason to omit a getter and have it public instead. 注意:对于常量(例如static final double LIGHT_SPEED ),有合理的理由省略getter并将其public This being just convention as it will be clear to what is a constant and what is an object with its own members. 这只是惯例,因为它将清楚什么是常量,什么是具有自己成员的对象。
    • NOTE2: Read about final keyword and its impact on optimization if interested. 注2:如果感兴趣,请阅读final关键字及其对优化的影响。 They can be used in methods as well as attributes. 它们既可以用于方法,也可以用于属性。 ( Does use of final keyword in Java improve the performance? is an example) 在Java中使用final关键字可以提高性能吗?就是一个例子)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对不可变类使用最终的私有或私有二传手 - Using final private or private setters for immutable classes 可以在Activity中使用私有构造函数,以便可以对变量使用final修饰符吗? - OK to use private constructor in Activity so I can use final modifier on variables? 何时使用私有访问修饰符或通过依赖注入保护,这对于使用 @Autowired 或最终密钥的 DI 来说是舒适的 - When to use access modifier private or protected with dependency injection,and which is comfortable for DI using @Autowired or final key 不可变类属性的需求必须与私有一起最终确定 - Need of Immutable class properties to be final along with private 我是否需要为 Java 中的所有不可变变量指定 «final» 修饰符? - Do I need to specify «final» modifier for ALL immutable variables in Java? 不可变对象中的private final vs public final字段(java) - private final vs public final fields in immutable objects (java) 私有构造函数和最终实例变量 - Private constructor and final instance variables 为什么在 class 中的抽象 class 中有私有访问修饰符,即使我们不能创建抽象 class 的实例? - Why is there a private access modifier in an abstract class in Java, even though we cannot create an instance of an abstract class? 为什么final是Java中局部变量的唯一修饰符? - Why is final the only modifier for local variables in Java? 将'final'修饰符与getter和setter一起使用是一个好主意吗? - Is it a good idea to use 'final' modifier with getters and setters?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM