我知道this
指的是当前对象,但我不知道什么时候需要使用它。例如,在某些方法中,如果我使用x
代替this.x
,是否会有任何区别?也许x
将引用只在该方法中可见的局部变量?
那么this.method()
呢?我可以使用它吗?我应该使用它吗?如果我只使用method()
,默认情况下它不会被应用于当前对象吗?
this
关键字主要有三种使用情况。第一种也是最常见的情况是在 setter 方法中用来消除变量引用的歧义。第二种情况是当需要将当前类实例作为参数传递给另一个对象的方法时使用。第三种情况是在构造函数内部调用其他构造函数的一种方式。
情况 1: 使用 this
来消除变量引用的歧义。在 Java 的 setter 方法中,我们通常会传入与私有成员变量相同名称的参数。然后,我们将参数 x
赋值给 this.x
。这样可以清楚地表明正在将参数 "name" 的值赋给实例变量 "name"。
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
情况2: 将this
用作传递给另一个对象的参数。
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
情况三: 使用this
调用其他构造函数。在评论中,trinithis正确指出了this
的另一个常见用法。当您为单个类拥有多个构造函数时,您可以使用this(arg0, arg1, ...)
来调用您选择的另一个构造函数,前提是您在构造函数的第一行这样做。
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
我也看到过在实例变量被引用时使用this
来强调这一事实(无需消除歧义),但在我看来这种情况很少见。
我认为这种使用方式很罕见,主要是为了强调使用的是实例变量而不是其他变量。
this
的第二个重要用途(除了像许多答案已经提到的使用局部变量隐藏之外),是在从嵌套非静态类访问外部实例时使用:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
当存在与本地变量名称重名的情况时,您只需要使用this
- 大多数人都只使用它。 (例如,setter方法)
当然,使用this
的另一个好处是它会在IDE中弹出智能感知提示 :)
只有当当前范围内的另一个变量与实例成员同名,并且您想要引用该实例成员时,才需要使用 this.
限定符(正如William所描述的那样)。除此之外,x
和 this.x
的行为没有区别。
this.x
使你的代码更易读。此外,代码的可维护性和可读性也是你应该考虑的因素之一。 - Astra在一个构造函数中调用另一个构造函数时,关键字"this"会很有用:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
有很多好的答案,但是还有一个非常微不足道的原因要在每个地方使用this
关键字。如果您尝试使用普通文本编辑器(例如记事本等)打开源代码,则使用this
将使其更加清晰易读。
想象一下:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
使用任何现代集成开发环境都可以轻松阅读,但在常规文本编辑器中阅读将是一场噩梦。
你将努力寻找foo
的位置,直到使用编辑器的“查找”功能。然后你会因为同样的原因而对getStringFromSomewhere()
大声抱怨。最后,在你忘记s
是什么之后,bar = s
将给你最后的打击。
与此相比:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
foo
是在外部类Hello
中声明的变量。getStringFromSomewhere()
也是在外部类中声明的方法。bar
属于World
类,而s
是在该方法中声明的局部变量。当然,在设计任何东西时,都需要创建规则。因此,如果您的API或项目的规则包括“如果有人使用记事本打开所有这些源代码,他或她应该朝自己的头开枪”,那么您完全可以不用做这件事。
this
在建造者模式中非常有用。
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
@William Brendel的回答以清晰的方式提供了三种不同的用例。
用例1:
官方Java文档页面this提供了相同的用例。
在实例方法或构造函数中,this是指当前对象的引用 - 调用方法或构造函数的对象。您可以使用this从实例方法或构造函数引用当前对象的任何成员。
它涵盖了两个示例:
使用Field和使用Constructor
用例2:
此帖子中未引用的其他用例:this
可用于同步多线程应用程序中的当前对象,以保护关键数据和方法的临界区。
synchronized(this){
// Do some thing.
}
用例3:
构建器模式的实现取决于使用this
来返回修改后的对象。
请参考此帖子
你对于变量的理解是正确的;this
确实可以用来区分方法变量和类字段。
private int x;
public void setX(int x) {
this.x=x;
}
然而,我真的很讨厌这种约定。给两个完全相同的变量命名是引发错误的一个因素。我更喜欢以下的写法:
private int x;
public void setX(int newX) {
x=newX;
}
结果相同,但没有机会在你打算引用x
时意外地引用了x
。
至于在方法中使用它,你对于效果的理解是正确的;你将得到相同的结果,无论是否使用它。你能使用它吗?当然可以。应该使用它吗?由你决定,但考虑到我个人认为它是毫无意义的冗余,不会增加任何清晰度(除非代码塞满了静态导入语句),我不倾向于自己使用它。
this(arg1, arg2, ...)
。 - Thomas Edingthis
的情况,因此我将其添加到了我的答案中。我认为这样做没有任何问题,因为最终结果是一个更好的答案,这正是SO的目的。我也尽可能地给予信用,就像我在trinithis的情况下所做的那样。 - William Brendel