2
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;

4

12 回答 12

4

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

你也可以看看这里

于 2010-05-19T11:40:49.953 回答
3
this.number

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

此外,您可以使用

numer += 5;

代替

setNumber(getNumber() + 5);

编辑:当然,在类之外它应该受到 getter/setter 的保护,因为您可以更改内部表示,并且您可以通过根据新状态表示重新实现它们来提供向后兼容性。

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

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

于 2010-05-19T11:41:50.967 回答
3

我会说这取决于情况。如果该字段很简单,例如 anint并且将来不太可能更改,我将使用numberand not访问它getNumber()

如果该字段表示涉及更多的东西,在某些情况下可能会在将来的情况下计算或可能在子类中被覆盖getNumber(),那么显然是选择。

我的经验法则:如果有任何微小的机会我可以从经历中受益,getNumber()我使用getNumber(),否则我使用number是为了清晰和简洁。

于 2010-05-19T11:51:40.687 回答
1

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

于 2010-05-19T11:52:25.457 回答
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 次方法调用。因此,在这种情况下,编译器不会对它有任何不同的处理。

于 2010-05-19T12:21:38.913 回答
0

数字

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

编辑:哦,你在课堂内的主要功能中使用它吗?然后就像另一个人说的那样,ofc e.getNumber()。

于 2010-05-19T11:41:04.580 回答
0

如果在同一类中使用,则编号。以及任何子类或外部任何地方的 e.getnumber

于 2010-05-19T11:44:11.997 回答
0

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

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

所以总结一下:我总是让成员保持私有并通过访问器访问它们,除非唯一需要的访问器是私有的。

于 2010-05-19T11:51:52.050 回答
0

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

我这样做是因为有时我想修改 getter 使其不仅仅是检索属性(例如延迟加载变量),而且我希望能够灵活地做到这一点而不必担心修改类的其他部分。

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

  1. 在实现我认为的“低级”功能时(这些完全是主观的,在我的情况下,我认为#equals(),#hashCode()#toString()“低级”)。我不认为这有很强的技术原因,只是对我来说“感觉”更好。
  2. 如果像其他人指出的那样使用设置器/获取器(例如num ++vs )太不方便了)。setNumber(getNumber() + 1
  3. 如果我的吸气剂确实做了一些额外的工作,并且在我的特殊情况下,我希望这种行为。
  4. ...而且可能还有其他我错过的情况...
于 2010-05-19T11:55:56.690 回答
0

用 this.number=.. 告别多线程,更不用说最终需要实现对 this.number 内部内容的控制。使用 setNumber() Java 得出结论,此方法可能是最终方法,并且可以通过优化进行很多操作,因此您感觉不到差异...

于 2010-05-19T12:10:25.823 回答
0

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

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

于 2010-05-19T12:19:13.473 回答
0

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

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

于 2010-05-19T15:42:49.057 回答