public class X
{
int a;
public void func(int a)
{
System.out.println(a);
System.out.println(this.a);
System.out.print(X.this.a);
}
public static void main(String ... args)
{
X var=new X();
var.func(5);
}
}
它给我的输出为 -
5 0 0
但为什么X.this工作,因为我们都知道“这个”在这个例子中是非静态的 -
public class Me
{
static Me m,m1;
int x;
public Me Me1()
{
System.out.println("yes");
return Me.this;
}
public static void main(String ... args)
{
m=new Me();
m1=new Me().Me1();
System.out.println(m.x+" "+m1.x);
}
}
现在这个程序正在运行但如果我把
public static Me Me1()
{
System.out.println("yes");
return Me.this;
}
然后它给出错误“非静态变量,这不能从静态上下文中引用”
我知道这是因为静态函数在对象创建之前存在,所以我们不能在任何非静态函数中使用“this”。
我的问题是为什么“this”可以像非Me.this一样从非静态函数中引用而没有任何错误..?
答案 0 :(得分:1)
为什么“this”可以像Me.this一样从非静态函数中引用而没有任何错误?
因为语言规范是这样说的。 Java允许内部/嵌套实例访问定义它们的(实例)类(外部类)。
<强> 15.8.4。合格
任何词汇封闭的实例(第8.1.3节)都可以通过明确限定关键字this来引用。
设C为ClassName表示的类。设n是一个整数,使得C是出现限定该表达式的类的第n个词汇封闭类。
ClassName.this形式的表达式的值是第二个词法封闭的实例。
表达式的类型是C.
如果当前类不是C类或C本身的内部类,则是编译时错误。
因此,由于您位于Me
课程范围内,因此可以使用this
和Me.this
,它们是等效的。如果您要从嵌套实例访问Me
,则必须使用Me.this
。
关于在静态上下文中使用this
。由于this
引用了您正在使用的类的当前实例,因此不能在静态方法中使用它。静态方法不属于任何实例,而是属于本身。也来自规范(15.8.3 - 见上一个链接):
当用作主表达式时,关键字
this
表示一个值,该值是对调用实例方法的对象(第15.12节)的引用,或者是对正在构造的对象的引用。
答案 1 :(得分:0)
当您调用非静态函数时,始终存在指定或隐含的目标对象。例如,如果调用System.out.println,则目标对象是System.out引用的对象。如果在没有指定目标的情况下调用自己类中的方法,则目标为this
。
然后,该方法可以使用this
来引用目标对象。如前所述,班级X.this
中的X
与this
相同。
答案 2 :(得分:0)
this
指的是类的当前实例。
另一方面,静态变量/方法是那些不适用于类的实例变量的方法(因此没有类的实例可用)。这就是您不能在静态方法中使用this
关键字的原因。
看看这个更容易理解的例子:
public class Person
{
String name;
public Person(String name)
{
this.name = name;
}
public void talk(String line)
{
System.out.println(name+": "+line);
}
}
用法如下:
Person a,b;
a = new Person("A");
b = new Person("B");
a.talk("hi!");
b.talk("hi");
注意talk()
方法如何使用成员(实例)变量name
。 talk()
可以改写为:
public void talk(String line)
{
System.out.println(this.name+": "+line);
}
这就是为什么a.talk()
会在消息之前打印“A:”,而b.talk()
会在消息之前打印“B:”。
现在让我们继续为课程添加另一种方法:
public class Person
{
String name;
public Person(String name)
{
this.name = name;
}
public void talk(String line)
{
System.out.println(name+": "+line);
}
public static void info()
{
System.out.println("You can create a person, using this class and make him talk to through the console");
}
}
您可以将info()
用作:
Person.info();
请注意,我使用的是类名,而不是实例名。这是因为静态(共享)变量在类的所有实例之间共享,而静态方法只能访问静态变量。
尝试将info()
更改为,您将收到错误消息:
public static void info()
{
System.out.println(name);
}
上面的代码会给你一个错误。因为name是一个实例变量,即在方法中使用name与使用this.name
相同。但是在当前上下文中不存在this
。
永远记住, 1.仅当属性/行为与实例变量的无关相同时,才使用静态变量/方法。 2.您不能直接从静态方法(或使用实例变量)调用非静态方法
public static void info()
{
talk();
}
无效,因为它与撰写this.talk()
相同
你必须做这样的事情:
public static void info()
{
Person a = new Person("Example");
a.talk();
}
您的代码设计需要改进。阅读有关Java和OO编程的书籍