Java中的“this”是指当前对象本身的引用。

159

通常情况下,我只在构造函数中使用this

我知道它用于通过使用this.something来标识参数变量(如果其与全局变量名称相同)。

然而,我不知道this在Java中的真正含义以及如果我没有使用点号(.),会发生什么。


8
给回答者们:http://meta.stackexchange.com/questions/15775/do-you-delete-your-own-answer-when-its-a-duplicate - BalusC
2
你好!各位SO的朋友们。你们可能也想参考一下我的这个问题 - https://dev59.com/SH_aa4cB1Zd3GeqPzSaK 谢谢。 - Erran Morad
Java中没有全局变量。 - user207421
22个回答

170

this指的是当前对象。

每个非静态方法都在对象的上下文中运行。所以如果你有一个像这样的类:

public class MyThisTest {
  private int a;

  public MyThisTest() {
    this(42); // calls the other constructor
  }

  public MyThisTest(int a) {
    this.a = a; // assigns the value of the parameter a to the field of the same name
  }

  public void frobnicate() {
    int a = 1;

    System.out.println(a); // refers to the local variable a
    System.out.println(this.a); // refers to the field a
    System.out.println(this); // refers to this entire object
  }

  public String toString() {
    return "MyThisTest a=" + a; // refers to the field a
  }
}

调用 new MyThisTest()frobnicate() 方法将打印:

1
42
MyThisTest a=42

因此,你可以用它来实现以下多个功能:

  • 当一个字段和其他某个东西具有相同名称时,澄清你正在谈论的是一个字段
  • 将当前对象作为一个整体引用
  • 在你的构造函数中调用当前类的其他构造函数

这不起作用。我收到了一个错误,说需要一个“main”方法。如果我添加主方法,那么我必须从那里调用。在主函数内调用frobnicate()的任何尝试都会显示无法从静态对象中调用非静态引用。删除"main"中的"static"将再次返回找不到主方法的错误。请解释一下。 - dbconfession
8
@dbconfession:这里的代码不是作为独立的、自运行的程序而存在的。你应该去“阅读”代码和文本,而不是运行它!这是有效的代码,但它只是为了演示目的而存在(这就是为什么它没有一个合适的主方法)。如果需要帮助理解主方法,请参考https://dev59.com/W3VC5IYBdhLWcg3w51vy。 - Joachim Sauer
@Joachim 谢谢!我对于什么是静态方法以及this.如何工作这些基础概念还有所欠缺。我的理解是,this.允许您调用一个方法或变量,该方法或变量是类的实例化版本所特有的,从而允许另一个版本的方法或变量存在,而不需要调用this.。在一个简单的名为Test.class的类中,我有两个方法:public static void main()public Test()。我无法在这两个方法之间传递信息,因为main是静态的,构造函数不能被定义为静态的。我应该发布一个新问题吗? - dbconfession
@dbconfession:我有一种感觉你的问题已经在其他地方得到了回答,但我不太明白你的问题是什么,所以你最好还是发出来(但要准备好被关闭为重复问题)。然而,在最基本的层面上,将一个方法设置为“静态”基本上意味着你不需要类的实例来调用它,并且你在其中没有访问“this”的权限。 - Joachim Sauer
@nsv0000:println有几个重载版本。如果你使用一个对象调用它,而这个对象不匹配任何其他版本,那么将会调用println(Object)版本。该版本被指定为在参数上调用toString()(通过String.valueOf())(如果它不是null)。这是一个常见的主题:当Java需要一个对象的字符串表示形式,并且没有指定其他内容时,通常会在对象上调用toString() - Joachim Sauer
显示剩余2条评论

55
以下是从这里复制粘贴的内容,但很好地解释了this关键字的所有不同用途: 定义:Java的this关键字用于引用其所在方法的当前实例。 以下是使用此关键字的方法:
  1. 明确指定实例变量而不是静态或局部变量。也就是说,

    private String javaFAQ;
    void methodName(String javaFAQ) {
        this.javaFAQ = javaFAQ;
    }
    

    这里的“this”指的是实例变量。在这里,本地变量的优先级较高。因此,没有使用this表示本地变量。如果局部变量(参数名称)与实例变量不同,则无论是否使用this,都表示实例变量。

    this用于引用构造函数。

     public JavaQuestions(String javapapers) {
         this(javapapers, true);
     }
    

    这会调用具有两个参数的相同Java类的构造函数。

  2. this 用于将当前的Java实例作为参数传递。

  3. obj.itIsMe(this);
    
    与上面类似,这也可以用来返回当前实例。
    CurrentClassName startMethod() {
         return this;
    }
    

    注意:在上述两种情况下在内部类中使用可能会导致不良结果,因为这将引用内部类而不是外部实例。

    this可用于获取当前类的句柄。

    Class className = this.getClass(); // this methodology is preferable in java
    

虽然这是可以通过以下方法实现的:

    Class className = ABC.class; // here ABC refers to the class name and you need to know that!

像往常一样,this 与它的实例相关联,在静态方法中无法使用。


48
为了完整起见,this也可以用来指代外部对象。
class Outer {
    class Inner {
        void foo() {
            Outer o = Outer.this;
    }
  }
}

6
这就是我一直在寻找的!;) - forresthopkinsa
4
那就太"超赞"了。 - killjoy

21
它指代特定对象的当前实例,因此您可以编写类似以下的内容
public Object getMe() {
    return this;
}

this 的一个常见用例是防止变量遮蔽。看下面的例子:

public class Person {
    private final String name;

    public Person(String name) {
        // how would we initialize the field using parameter?
        // we can't do: name = name;
    }
}

在上面的例子中,我们想要使用参数的值来赋值字段成员。由于它们具有相同的名称,我们需要一种区分字段和参数的方法。this 允许我们访问此实例的成员,包括该字段。
public class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }
}

5
在调用它时要注意使用适当的语法风格:o.getMe().getMe().outOfHere()。 - Justin K

9

引用 programming.guide 上的 文章


this在Java程序中有两种用途。

1. 作为当前对象的引用

在这种情况下,语法通常如下所示:

this.someVariable = someVariable;

这种用法在这里描述:使用'this'引用的例子 2. 调用不同的构造函数
在这种情况下,语法通常看起来像这样:
MyClass() {
    this(DEFAULT_VALUE); // delegate to other constructor
}

MyClass(int value) {
    // ...
}

这种用法在此处描述:使用(…)构造函数调用(附例)

8
在Swing中,编写实现ActionListener的类,并将当前实例(即“this”)添加为组件的ActionListener,是相当常见的。
public class MyDialog extends JDialog implements ActionListener
{
    public MyDialog()
    {
        JButton myButton = new JButton("Hello");
        myButton.addActionListener(this);
    }

    public void actionPerformed(ActionEvent evt)
    {
        System.out.println("Hurdy Gurdy!");
    }

}

7

这实际上是“当前上下文中对象的引用”。例如,要打印出“此对象”,您可以编写:

System.out.println(this);

请注意,您对“全局变量”的使用有些不恰当...如果您使用的是this.variableName,那么根据定义,它不是全局变量-它是特定于此特定实例的变量。

6
它指的是调用该方法的实例。
class A {

  public boolean is(Object o) {
    return o == this;
  }

}

A someA = new A();
A anotherA = new A();
someA.is(someA); // returns true
someA.is(anotherA); // returns false

4

this关键字用于引用块的当前变量,例如考虑下面的代码(只是一个例子,不要期望标准JAVA代码):

Public class test{

test(int a) {
this.a=a;
}

Void print(){
System.out.println(a);
}

   Public static void main(String args[]){
    test s=new test(2);
    s.print();
 }
}

就这样,输出结果将会是"2"。 如果我们没有使用this关键字,那么输出结果将会是: 0


3

对象具有从类派生的方法和属性(变量),为了指定哪些方法和变量属于特定的对象,使用this保留字。在实例变量的情况下,理解隐式参数和显式参数之间的区别非常重要。看一下audi对象的fillTank调用。

Car audi= new Car();

audi.fillTank(5); // 5 is the explicit parameter and the car object is the implicit parameter 

括号中的值是隐式参数,对象本身是显式参数。没有显式参数的方法使用隐式参数,`fillTank` 方法既有显式参数也有隐式参数。让我们仔细看一下 `Car` 类中的 `fillTank` 方法。
public class Car()
{
   private double tank;

   public Car()
   {
      tank = 0;
   }

   public void fillTank(double gallons)
   {
      tank = tank + gallons;
   }

}

在这个类中我们有一个实例变量"tank"。有许多对象可以使用"tank"实例变量,为了指定实例变量"tank"用于特定的对象,在我们的例子中是先前构造的"audi"对象,我们使用保留关键字"this"。对于"实例变量"而言,在"方法"中使用"this"表示实例变量,即在我们的情况下是"tank",是隐式参数的实例变量。
Java编译器会自动添加"this"保留字,因此您不必添加,这是一种偏好。不能在没有点(.)的情况下使用"this",因为这是Java语法规则。
总之:
- 对象由类定义,并拥有方法和变量 - 在"方法"中使用"this"对于"实例变量"表示,该实例变量属于隐式参数或是隐式参数的实例变量。 - 隐式参数是在本例中调用该方法的对象"audi"。 - Java编译器会自动添加"this"保留字,添加它是一种偏好。 - "this"不能在没有点(.)的情况下使用,因为它在语法上无效。 - "this"也可用于区分具有相同名称的局部变量和全局变量。 - "this"保留字也适用于方法,以表示方法属于特定对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接