Java语言约定;吸气剂/吸气剂

发布于 2024-09-02 20:13:44 字数 552 浏览 11 评论 0原文

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; 一样快吗?

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

What is preffered when accessing a variable within its own class;
"e.number" or "e.getNumber()" ?

Edit:
I think the most important question is: does the compiler know the method you call is a getter or setter. So, will e.setNumber(5); be as fast as e.number = 5;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

失而复得 2024-09-09 20:13:44

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

您还可以此处查看。

e.getNumber() is the common approach. So get or set + VariableName.

You could also have a look HERE.

眼藏柔 2024-09-09 20:13:44

我想说这要看情况。如果该字段很简单,例如 int 并且将来不太可能更改,我将使用 number 而不是 访问它getNumber()。

如果该字段表示更复杂的内容,在某些情况下可能在将来的情况下计算或者可能在子类中覆盖,则 getNumber() 是显而易见的选择。

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

I would say it depends on the situation. If the field is something simple such as an int and unlikely to change in the future, I would access it using number and not getNumber().

If the field represents something more involved that could in some situation perhaps be computed in future situation or possibly overridden in a subclass, getNumber() is the obvious choice.

My rule of thumb: If there is any remote chance that I can benefit from going through getNumber() I use getNumber(), otherwise I use number for clarity and brevity.

久夏青 2024-09-09 20:13:44
this.number

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

此外,您可以使用

numer += 5;

而不是

setNumber(getNumber() + 5);

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

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

main 的速度而言,无论如何,启动 JVM 都会抵消任何成本,这并不重要。真正的区别在于 JIT 会处理的内部循环。

this.number

In most cases they will be optimized to the same code but the point of using setters/getters is to avoid changin API in case of change of implementation. However in class you don't use "API" but you see all the internals and state.

Additionally you can use

numer += 5;

instead of

setNumber(getNumber() + 5);

Edit: Of course outside class it shoudl be protected by getter/setter as you may change internal representation and you can provide backward-compatibility by reimplementing them in terms of new state representation.

Edit 2: main is a bit special. I'd say that main should be as minimal as possible - create some objects and call one or two methods maximum - hence it should not assign variebles and should be threated as 'external' part. On the other hand some provides tests methods in main which may require accessing state directly. So if you can you should not directly access fields in main.

As of speed in main it does not matter anyway as starting the JVM would offset any costs. The real difference would be in the inner loops in which JIT would take care about it.

非要怀念 2024-09-09 20:13:44

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

There will only be a difference if the getter/setter does something extra. If you know from the start this will be the case, then use the methods even within the class. If not I'd just go with the direct field manipulation and rely on Eclipse to help me with the refactoring later if necessary.

雄赳赳气昂昂 2024-09-09 20:13:44

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

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 个方法调用。因此,在这种情况下,编译器不会对它进行任何不同的处理。

To answer your last question, look at this example,

Java Code:

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

Byte Code:

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

As you can see, the bytecode still makes the 2 method calls. So the compiler doesn't treat it any differently in this case.

我的黑色迷你裙 2024-09-09 20:13:44

number

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

编辑:哦,你想在类的主函数中使用它吗?然后 ofc e.getNumber() 正如另一个人所说。

number

Except number is a private member of a base class. Then i use the getter/setter to make clear, its not a member of the extending class.

Edit: Oh you ment using it in the main function inside the class? Then ofc e.getNumber() as the other guy said.

仙女 2024-09-09 20:13:44

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

number if it is used in the same class. And e.getnumber in any subclasses or anywhere outside

⒈起吃苦の倖褔 2024-09-09 20:13:44

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

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

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

If the public accessor exists for another purpose, it's preferable to use this accessor, since you'll ensure consistent access to your variable.

However, if your variable does not have a public accessor, it is considered acceptable to access the variable directly. I tend to restrain that to private variables (i.e. no private accessors in the code, but protected accessors instead of protected members if you need access in an implementation of the base class).

So to summarize : I'd always keep the members private and access them through accessors, except if the only accessors needed are private.

格子衫的從容 2024-09-09 20:13:44

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

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

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

  1. 在实现我认为的“低级”功能时(这些完全是主观的,就我而言,我考虑 #equals()#hashCode()#toString() 等“低级”)。我认为这没有很强的技术原因,只是我“感觉”更好。
  2. 如果使用 setter/getter 太不方便(例如,num ++ vs setNumber(getNumber() + 1),正如其他人指出的那样)。
  3. 如果我的 getter 确实做了一些额外的工作,并且在我的特定情况下,我想要这种行为。
  4. ...而且可能还有其他我错过的案例...

I generally prefer to still go through the setters/getters, even when accessing the class internally.

I do this because there may be times I want to modify the getters so that it does more than just retrieving a property (e.g., lazy load variable), and I want to have the flexibility of being able to do that without having to worry about modifying other parts of the class.

That said, there are exceptions, though these are for the most part, more personal preference than general best practice. I'll access member variables directly:

  1. When implementing what I consider "low level" functionality (and these are totally subjective, in my case, I consider #equals(), #hashCode(), #toString() and the like "low level"). I don't think there's a very strong technical reason for this, it just "feels" better to me.
  2. If it is way too inconvenient to use the setters/getters (e.g., num ++ vs setNumber(getNumber() + 1) as someone else pointed out).
  3. If my getter does do some additional work, and in my particular case, I do not want that behavior.
  4. ...And there are probably other cases I've missed...
帅冕 2024-09-09 20:13:44

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

say goodbye to multithreading with this.number=.. not to mention eventual need for implementing control of what can be inside this.number. With setNumber() Java concludes this method could be final and can make alot with optimization so you can't sense the difference...

她说她爱他 2024-09-09 20:13:44

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

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

Getters/setters are nice in that they often may do slightly more than act as the interface to a private field. The value returned/set may be a part of a more complex calculation that goes on behind the scenes.

The danger however, is that because they are fully fledged method calls, they can literally do anything - start a process, download a file, do an expensive task etc. This is of course silly from the context of a getter/setter but is something to avoid doing. I've also heard of code that performs most of what it's meant to do in getters/setters, having no real methods!!

倾城°AllureLove 2024-09-09 20:13:44

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

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

The JVM will optimize away the method call of the setter whenever it is safe to do so (i.e. under almost any case where you would be tempted to just use the field). So for performance, it ought not matter unless you're running on a JVM that doesn't do JIT compilation (e.g. Dalvik). In fact, you can chain method calls many levels deep and the JVM will optimize it away to just a field access when it actually runs it on hardware.

So you generally need not worry about performance costs associated with getters/setters unless they are genuinely doing something extra (which, here, they are not). You can instead make the decision based on other criteria (do you want the flexibility to change the underlying representation? do you want to redefine it in later classes, and if so, is the redefined setter/getter correct, or is the field access correct? etc.).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文