在Java中使用`this`关键字可以接受的样式是什么?


37

我来自Python或Javascript之类的语言(以及其他一些不太面向对象的语言),并且我试图提高我的Java工作知识,而我只是以肤浅的方式知道这些知识。

总是this在当前实例属性之前添加前缀是否被认为是不好的做法?我觉得写起来更自然

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

因为它可以帮助我区分实例属性和局部变量。

当然,在像Javascript这样的语言中,始终使用会更有意义this,因为可以嵌套更多的函数,因此局部变量来自更大的作用域。据我了解,在Java中,这样的嵌套是不可能的(内部类除外),因此可能不是什么大问题。

无论如何,我都倾向于使用this。会觉得很奇怪而不是习惯吗?


我们使用工具对我们公司进行标准化。没有公司的情况下,该工具会根据我们的公司政策来重新编码代码。因此,每个人都可以编写自己喜欢的代码,并在提交时以正确的方式格式化代码。
deadalnix 2011年

2
“由于可以嵌套更多的函数,因此局部变量来自更大的作用域。” 另外,“ this”实际上不是JS函数中不合格变量所来自的地方之一。
2011年

2
我为所有实例变量加上下划线前缀,因此无需使用就能轻松分辨出本地变量和实例变量之间的区别this
WuHoUnited 2011年

4
在C#中,StyleCop希望您this.在引用成员变量,方法等时放。我喜欢这一点,我同意这一规则。我认为这比起初用下划线命名要好。如果我使用Java进行编码,我将遵循相同的规则。
工作

Answers:


40

在大多数IDE中,如果您想知道,只需将鼠标悬停在变量上即可。另外,实际上,如果您正在使用实例方法,则应该真正了解所涉及的所有变量。如果太多,或者它们的名称冲突,则需要重构。

这真的很多余。


7
另外:理智的IDE应该使字段和局部变量/参数在视觉上有所区别。例如,在Eclipse中(默认情况下),字段为蓝色,而局部变量为黑色。
约阿希姆·绍尔

1
@Joachim好的一点,如果用户愿意,Eclipse甚至可以为参数和局部变量设置不同的颜色(但是默认情况下不是)。
埃里克·卡尔

3
尽管我同意,但是在遇到其他开发人员的代码时(乍一看却不熟悉),我发现它会this.提供更多帮助。这也可能是因为我没有IDE对本地/对象变量进行不同颜色编码的IDE。
布拉德·克里斯蒂

3
+1(释义)“重构,如果您需要使用来推断它是成员”。我想指出的就是这一点。
Yam

我没有发现它使阅读变得更困难,因此,代码在编辑器中仍保持可读性,这些编辑器的语法突出显示不太复杂,无法区分字段和本地。我一直认为,您应该努力使您的代码在最基本的文本编辑器中易于阅读,如果不是这样,应该有充分的理由。
凯文(Kevin)

26

我更喜欢使用this。它使在以相同方式为本地变量和实例变量着色的各种编辑器中阅读代码变得更加容易。它还使在进行代码检查之类的过程中,更容易读取打印页面上的代码。对于其他开发人员来说,这也是一个很强烈的变量提示范围。

但是,对此有反对意见。在现代IDE中,可以通过将变量悬停在变量上或以树状结构查看变量的范围来找到它的范围。您还可以根据变量的范围来更改颜色和/或字体的外观(即使以这种方式在打印时也可以清楚地看到变量的范围是什么)。

我相信ChrisF的最后一句话已经死了:请保持一致。


7
“这对于其他开发人员来说,也很强烈地提醒了该变量的范围。” -我倾向于使用并且喜欢this.在代码中看到的原因。花费半秒钟的时间写,可以节省很长时间,因为当他在20修订版的最后一刻进行更改时,必须弄清您之前的那个家伙是否真的打算使用pascal-case属性而不是本地的camel-case属性。
scrwtp 2011年

18

我一直使用“ this”的地方是setter和or构造函数:

public void setFoo(String foo) {
    this.foo = foo;
}

除此之外,我认为没有必要添加它。读取方法的主体时,参数和局部变量就在其中-并且相当容易跟踪(即使没有IDE帮助)。同样,局部变量和字段具有不同的性质(对象状态与瞬态存储或参数)。

如果对什么是变量和什么字段存在任何混淆,则可能意味着方法具有太多的变量/参数,太长和太复杂,应该简化。

如果您选择使用'this'标记字段,我建议确保始终严格遵守约定-假设没有'this'意味着它是本地的并且基于假设破坏东西,那么开始就很容易。

编辑:我也最终在equals,clone或具有相同对象类型的'that'参数的任何东西中使用此方法:

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}

8

这值得商.。

以C#为类比,因为它的语法和结构与Java非常相似,我们发现C#StyleCop具有一个默认规则,该规则要求您添加this,但是ReSharper具有一个默认规则,该规则表明this冗余(是),并且可以删除。

因此,如果您使用一种工具,则将其添加,而如果使用另一种工具,则将其删除。如果同时使用这两种工具,则必须选择并禁用其中一项规则。

但是,规则的实际含义是您的用法保持一致-这可能是最重要的事情。


8

始终在当前实例属性之前添加它是否被认为是不好的做法?

是的-有些人,没有-其他人。

我喜欢this在Java和C#项目中使用关键字。有人可能会说IDE总是会用不同的颜色突出显示参数和字段,但是我们并不总是在IDE中工作-我们必须做很多合并/比较/在记事本中进行一些快速更改/检查电子邮件中的一些代码片段。它的方式更容易为我从第一次看哪里实例的状态改变现货-例如,审查一些可能并发问题。


7

我认为,如果您需要使用此方法,则要么方法太长,要么是一个类试图做太多事情,或者两者兼而有之。

方法的长度不应超过几行代码,而应使用一个或两个局部变量来确定什么变得容易。即使只有大多数diff工具的3行内容也是如此。如果您的方法太长,并且您的类有太多的职责(通常意味着太多的字段),则解决方案是将它们拆分。

我认为“这个”只会使代码混乱。尤其是对于现代IDE,它将对局部参数/局部变量/字段进行不同的着色。


5

我认为您以此回答了自己的问题

我觉得写起来更自然

... this.foo ...

...富...

因为它可以帮助我区分实例属性和局部变量。

如果您在使用this.Java改善工作知识的同时更习惯使用,那么一定要使用它(在某种程度上,我认为这是您所熟悉的Python自身)。

事实是,尽管人们会就使用或不使用提供固执/相关的论据this.,但这仍然像是一场辩论,下面给出了示例:

  • 它使变量的目的明确你应该重写代码,如果它不是明确每个变量是什么;
  • this.是多余的,如果你花你一整天的IDE 我在使用不带语法高亮比较不同版本进行代码审查并作出比较;
  • 不打字可以使this.我获得重要的毫秒生产率,按键盘键this.给我报酬,而增加就像加薪:D;

但最重要的是,归根结底,它仍然会恢复为个人喜好和工作环境


5

通常添加是不必要的。我认为这本身并不是不好的做法,但是在我所见过的大多数Java代码库中,过度使用可能被认为是不寻常的。

但是,我发现它在某些特定情况下很有价值:

覆盖局部参数 -有时有必要指定您要使用实例变量,而不是同名的参数/局部变量。这在构造函数中很常见,在该构造函数中,您希望参数名称与用于初始化的实例变量的内部名称匹配,例如

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

当处理同一个类的其他实例时 -我相信它可以使代码更清晰,更易理解,从而可以清楚地指出您所引用的类的哪个实例,例如

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.