提问人:Roman 提问时间:3/10/2010 最后编辑:Gabriel ŠčerbákRoman 更新时间:4/10/2020 访问量:289313
我应该在课堂上什么时候使用“this”?
When should I use "this" in a class?
问:
我知道这是指当前对象。但我不知道什么时候真正需要使用它。例如,如果我使用而不是某些方法,会有什么区别吗?可能是指所考虑方法的局部变量?我的意思是仅在此方法中看到的变量。this
x
this.x
x
怎么样?我可以使用它吗?我应该使用它吗?如果我只使用 ,默认情况下它不会应用于当前对象吗?this.method()
method()
答:
该关键字主要用于三种情况。第一种也是最常见的是在 setter 方法中,用于消除变量引用的歧义。第二种是当需要将当前类实例作为参数传递给另一个对象的方法时。第三种是从构造函数中调用备用构造函数的一种方式。this
案例一:用于消除变量引用的歧义。在 Java setter 方法中,我们通常传入一个与我们尝试设置的私有成员变量同名的参数。然后,我们将参数赋值给 。这清楚地表明,您正在将参数 “name” 的值分配给实例变量 “name”。this
x
this.x
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
案例二:用作传递给另一个对象的参数。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();
}
}
案例三:用于调用备用构造函数。在评论中,trinithis 正确地指出了 .当单个类有多个构造函数时,可以使用调用所选的另一个构造函数,前提是在构造函数的第一行中执行此操作。this
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(arg1, arg2, ...)
this
this
除非你有重叠的变量名称,否则它实际上只是为了在你阅读代码时清楚起见。
评论
this
this
唯一需要使用限定符的是,当前作用域中的另一个变量具有相同的名称,并且您想要引用实例成员(如 William 描述的那样)。除此之外,和 之间的行为没有区别。this.
x
this.x
评论
this.x
如果我在某些方法中使用“x”而不是“this.x”会有什么区别吗?
通常不会。但有时它会有所不同:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
如果我只使用“method()”,默认情况下它不会应用于当前对象吗?
是的。但如果需要,请阐明调用是由此对象发出的。this.method()
你只需要使用--大多数人只在有一个同名的重叠局部变量时才使用它。(例如,Setter 方法。this
当然,使用的另一个很好的理由是,它会导致智能感知在 IDE 中弹出:)this
评论
this
不影响生成的代码 - 它是编译时运算符,无论有没有它,生成的代码都是相同的。何时必须使用它,取决于上下文。例如,正如您所说,当您有遮蔽类变量的局部变量并且您想要引用类变量而不是局部变量时,您必须使用它。
编辑:我的意思是“生成的代码将是相同的”,当然,当局部范围内的某些变量不隐藏属于类的变量时。因此
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
这两种方法的结果代码将是相同的。区别在于,如果某个方法声明了同名的局部变量
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
谷歌在Sun网站上发现了一个页面,对这个问题进行了一些讨论。
你对变量的看法是对的; 确实可以用来区分方法变量和类字段。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
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”在从一个构造函数调用另一个构造函数时也很有用:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
确保使用当前对象的成员。在考虑线程安全的情况下,某些应用程序可能会更改错误的对象成员值,因此应将其应用于成员,以便使用正确的对象成员值。
如果对象与线程安全无关,则没有理由指定使用哪个对象成员的值。
评论
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();
}
}
评论
this
是对当前对象的引用。它在构造函数中用于区分具有相同名称的局部类变量和当前类变量。例如:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this
还可用于从另一个构造函数调用一个构造函数。例如:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Brendel@William回答以很好的方式提供了三种不同的用例。
用例 1:
关于此的官方 Java 文档页面提供了相同的用例。
在实例方法或构造函数中,这是对当前对象的引用,该对象是调用其方法或构造函数的对象。您可以使用它从实例方法或构造函数中引用当前对象的任何成员。
它包括两个例子:
将 this 与 Field 一起使用,并将其与构造函数一起使用
用例 2:
本文未引用的其他用例:可用于同步多线程应用程序中的当前对象,以保护数据和方法的关键部分。this
synchronized(this){
// Do some thing.
}
用例 3:
Builder 模式的实现依赖于 返回修改后的对象。this
请参阅此帖子
将构建器保留在单独的类中(Fluent interface)
以下是在 java 中使用 'this' 关键字的方法:
- 使用关键字引用当前类实例变量
this
- 用于调用当前类构造函数
this()
- 使用关键字返回当前类实例
this
- 使用关键字作为方法参数
this
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
关于威廉·布伦德尔(William Brendel)的帖子和dbconfessions问题,关于案例2。下面是一个示例:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
我已经看到,在与对象建立父子关系时,它被使用了。但是,请注意,为了简洁起见,它进行了简化。
有很多好的答案,但还有另一个非常小的理由可以放到任何地方。如果您尝试过从普通的文本编辑器(例如记事本等)打开源代码,那么使用将使阅读更加清晰。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;
}
}
}
使用任何现代 IDE 阅读都非常清楚,但使用常规文本编辑器阅读这将是一场噩梦。
在使用编辑器的“查找”功能之前,您将很难找到驻留位置。然后你会因为同样的原因而尖叫。最后,在你忘记了是什么之后,这将给你最后一击。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 或项目时,如果你的规则包括“如果有人用记事本打开所有这些源代码,他或她应该朝自己的头部开枪”,那么你完全可以不这样做。
评论
上一个:箭头函数和这个 [重复]
评论