Java语言惯例; getter / setter方法

时间:2010-05-19 11:39:01

标签: java performance program-flow

Public class Example {

    private int number;

    public Example(int number){
        this.number = number;
    }

    public int getNumber(){
        return number;
    }

    public void setNumber(int number){
        this.number = number;
    }

    public static void main(String[] args){
        Example e = new Example(5);

访问其自己的类中的变量时提供的内容; “e.number”或“e.getNumber()”?

修改
我认为最重要的问题是:编译器是否知道您调用的方法是getter或setter。因此,e.setNumber(5);e.number = 5;

一样快

12 个答案:

答案 0 :(得分:4)

e.getNumber()是常用方法。所以getset + VariableName

您还可以查看HERE

答案 1 :(得分:3)

this.number

在大多数情况下,它们将针对相同的代码进行优化,但使用setter / getter的目的是在更改实现时避免使用changin API。但是在课堂上你不使用“API”,但你会看到所有的内部和状态。

此外,您可以使用

numer += 5;

而不是

setNumber(getNumber() + 5);

编辑:当然在课外,它应该受到getter / setter的保护,因为你可以改变内部表示,你可以通过在新的状态表示方面重新实现它们来提供向后兼容性。

编辑2 main有点特别。我会说main应该尽可能小 - 创建一些对象并最多调用一个或两个方法 - 因此它不应该分配变量并且应该被威胁为“外部”部分。另一方面,一些提供main中的测试方法,这些方法可能需要直接访问状态。因此,如果可以,您不应直接访问main中的字段。

至于main的速度,无论如何,启动JVM都会抵消任何成本。真正的区别在于JIT会关注它的内部循环。

答案 2 :(得分:3)

我想说这取决于具体情况。如果该字段很简单,例如int将来不太可能更改,我会使用number而不是getNumber()来访问它。

如果字段代表更多涉及的内容,在某些情况下可能在未来情况下计算或可能在子类中重写getNumber()是显而易见的选择。

我的经验法则:如果我可以通过getNumber()获得任何远程机会,我会使用getNumber(),否则我会使用number清晰和简洁。

答案 3 :(得分:1)

如果getter / setter做了额外的事情,那将只会有所不同。如果您从一开始就知道这种情况,那么即使在类中也使用这些方法。如果不是,我只是采用直接字段操作,并在必要时依赖Eclipse帮助我进行重构。

答案 4 :(得分:1)

要回答您的上一个问题,请查看此示例

Java代码:

public void test2() {
    setNumber(getNumber() + 1);
}

字节代码:

public test2()V
   L0
    LINENUMBER 47 L0
    ALOAD 0
    ALOAD 0
    INVOKEVIRTUAL com/test/ByteCodeTester.getNumber()I
    ICONST_1
    IADD
    INVOKEVIRTUAL com/test/ByteCodeTester.setNumber(I)V
   L1
    LINENUMBER 48 L1
    RETURN
   L2
    LOCALVARIABLE this Lcom/test/ByteCodeTester; L0 L2 0
    MAXSTACK = 3
    MAXLOCALS = 1

如您所见,字节码仍然进行2方法调用。因此,在这种情况下,编译器不会对它进行任何不同的处理。

答案 5 :(得分:0)

除了number是基类的私有成员。然后我使用getter / setter来表明它,它不是扩展类的成员。

编辑:哦,你在类里面的main函数中使用它吗?然后是另一个人说的e.getNumber()。

答案 6 :(得分:0)

如果它在同一个类中使用,则为数字。并且e.getnumber在任何子类或

之外的任何地方

答案 7 :(得分:0)

如果公共访问者存在用于其他目的,则最好使用此访问者,因为您将确保对变量的一致访问。

但是,如果您的变量没有公共访问器,则直接访问变量被认为是可接受的。我倾向于将其限制为私有变量(即代码中没有私有访问器,但如果需要在基类的实现中进行访问,则受保护的访问者而不是受保护的成员。)

总而言之:我总是将成员保密,并通过访问器访问它们,除非所需的唯一访问者是私有的。

答案 8 :(得分:0)

我通常更喜欢仍然通过setter / getters,即使在内部访问类时也是如此。

我之所以这样做是因为有时候我想要修改getter以便它不仅仅是检索一个属性(例如,延迟加载变量),而且我希望能够灵活地做到这一点而不需要担心修改班级的其他部分。

尽管如此,有一些例外,尽管这些是大多数情况下的个人偏好,而不是一般的最佳实践。我将直接访问成员变量:

  1. 在实施我认为的“低级”功能时(这些是完全主观的,在我的情况下,我认为#equals()#hashCode()#toString()之类的“低级别” )。我不认为这有一个非常强大的技术原因,它对我来说“感觉”更好。
  2. 如果使用setter / getters(例如,num ++ vs setNumber(getNumber() + 1)太不方便,就像其他人指出的那样。)
  3. 如果我的getter确实做了一些额外的工作,并且在我的特定情况下,我想要这种行为。
  4. ......可能还有其他一些我错过了......

答案 9 :(得分:0)

告诉多线程使用this.number = ..更不用说最终需要实现对this.number中的内容的控制。使用setNumber()Java得出结论,这个方法可能是最终的,并且可以进行很多优化,因此你无法感知差异......

答案 10 :(得分:0)

Getters / setter很不错,因为它们通常可以作为私有字段的接口。返回/设置的值可能是幕后更复杂计算的一部分。

然而,危险在于,因为它们是完全成熟的方法调用,它们可以完全做任何事情 - 启动进程,下载文件,执行昂贵的任务等。这当然是从getter / setter的上下文中愚蠢的但是要避免这样做。我也听说过代码可以执行getter / setter中的大部分操作,没有真正的方法!!

答案 11 :(得分:0)

只要安全,JVM就会优化掉setter的方法调用(即几乎任何情况下你都会想要使用该字段)。因此,对于性能而言,除非您在不进行JIT编译的JVM上运行(例如Dalvik),否则无关紧要。实际上,您可以将方法调用链接到很多级别,并且当JVM实际在硬件上运行时,JVM会将其优化为只是一个字段访问。

所以你通常不必担心与getter / setter相关的性能成本,除非他们真正做了额外的事情(在这里,他们不是)。您可以根据其他条件做出决定(您是否希望灵活地更改基础表示?是否要在以后的类中重新定义它,如果是,重新定义的setter / getter是否正确,或者字段访问是否正确?等。)。