是关键字'this'是一个静态的东西..?

时间:2013-12-07 17:08:01

标签: java

好吧,我正在编写一个程序,并坚持说明为什么它正在运行......这是我的代码。

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一样从非静态函数中引用而没有任何错误..?

3 个答案:

答案 0 :(得分:1)

为什么“this”可以像Me.this一样从非静态函数中引用而没有任何错误?

因为语言规范是这样说的。 Java允许内部/嵌套实例访问定义它们的(实例)类(外部类)。

来自language specification

  

<强> 15.8.4。合格

     

任何词汇封闭的实例(第8.1.3节)都可以通过明确限定关键字this来引用。

     

设C为ClassName表示的类。设n是一个整数,使得C是出现限定该表达式的类的第n个词汇封闭类。

     

ClassName.this形式的表达式的值是第二个词法封闭的实例。

     

表达式的类型是C.

     

如果当前类不是C类或C本身的内部类,则是编译时错误。

因此,由于您位于Me课程范围内,因此可以使用thisMe.this,它们是等效的。如果您要从嵌套实例访问Me,则必须使用Me.this

关于在静态上下文中使用this。由于this引用了您正在使用的类的当前实例,因此不能在静态方法中使用它。静态方法不属于任何实例,而是属于本身。也来自规范(15.8.3 - 见上一个链接):

  

当用作主表达式时,关键字this表示一个值,该值是对调用实例方法的对象(第15.12节)的引用,或者是对正在构造的对象的引用。

答案 1 :(得分:0)

当您调用非静态函数时,始终存在指定或隐含的目标对象。例如,如果调用System.out.println,则目标对象是System.out引用的对象。如果在没有指定目标的情况下调用自己类中的方法,则目标为this

然后,该方法可以使用this来引用目标对象。如前所述,班级X.this中的Xthis相同。

答案 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()方法如何使用成员(实例)变量nametalk()可以改写为:

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编程的书籍

相关问题