📜  为什么不能从Java中的静态方法引用非静态变量

📅  最后修改于: 2022-05-13 01:54:30.116000             🧑  作者: Mango

为什么不能从Java中的静态方法引用非静态变量

Java是最流行和广泛使用的编程语言和平台之一。 Java是面向对象的。但是,它不被视为纯面向对象,因为它提供了对原始数据类型(如 int、char 等)的支持。在Java中,方法可以声明为静态或非静态。在本文中,让我们讨论为什么不能从静态方法中引用非静态变量。
在进入错误之前,让我们首先了解每种方法的含义:

  • 静态方法:静态方法是属于某个类的方法,但它不属于该类的实例,并且可以在没有该类的实例或对象的情况下调用该方法。在静态方法中,该方法只能访问另一个类或同一个类的静态数据成员和静态方法,而不能访问非静态方法和变量。
  • 非静态方法:定义中不包含 static 关键字的任何方法都是非静态方法。在非静态方法中,方法可以访问静态数据成员和静态方法,也可以访问另一个类或同一个类的非静态成员和方法,也可以改变任何静态数据成员的值。

从静态上下文引用的非静态变量有什么问题?
让我们考虑以下代码,其中使用非静态变量和静态方法创建类 A。该类的对象正在另一个类中创建,并且正在访问静态方法,如下所示:

JAVA
// Java program to demonstrate
// why a non-static variable cannot
// be accessed from a static context
 
// Creating a class A
class A {
 
    // A non-static variable
    int N;
 
    // Static method
    public static void increment()
    {
          // this throws a compile - time error.     
        N++;
    }
}
 
public class Demo {
 
    // Main method
    public static void main(String args[])
    {
        // Creating multiple objects
        // for class A
        A obj1 = new A();
        A obj2 = new A();
        A obj3 = new A();
 
        // Assigning the different values
        // for the non static variable N
        obj1.N = 3;
        obj2.N = 4;
        obj3.N = 5;
 
        // Calling the method
        A.increment();
 
        System.out.println(obj1.N);
        System.out.println(obj2.N);
        System.out.println(obj3.N);
    }
}


Java
// Java program to access a
// non static variable from
// a static block
public class GFG {
 
    int count = 0;
 
    // Driver code
    public static void main(String args[])
    {
 
        // Accessing static variable
        // by creating an instance
        // of the class
        GFG test = new GFG();
 
        test.count++;
        System.out.println(test.count);
    }
}


如果此代码实际上可以运行,您会期望输出为:

4
5
6

但是会引发编译时错误

Compile Errors:

prog.java:16: error: non-static variable N cannot be referenced from a static context
        N++;
        ^
1 error

正如我们所看到的,上面的程序给出了错误。虽然在上面的代码中,所有的对象名称都具有相同的变量名称 N,但如果我们尝试增加 N,则会出错。这个错误在面向对象编程中很常见。
为什么会出现这个错误?
对于非静态变量,需要一个对象实例来调用这些变量。我们还可以通过为该非静态变量分配不同的值来创建多个对象。因此,不同的对象可能对同一个变量有不同的值。在上面的程序中,我们为类 A创建了三个对象obj1obj2obj3 ,并分别为对象obj1obj2obj3分配了三个不同的值345 。当我们尝试调用函数increment时,由于N的每个对象都有自己的值,因此编译器在理解 N 的什么值应该让该方法增加值时会产生歧义。
如何解决这个错误?
为了避免歧义, Java编译器会抛出编译时错误。因此,可以通过使用对象名称寻址变量来解决此问题。简而言之,我们总是需要创建一个对象才能从静态上下文中引用非静态变量。每当创建新实例时,都会创建所有非静态变量和方法的新副本。通过使用新实例的引用,可以访问这些变量。例如:

Java

// Java program to access a
// non static variable from
// a static block
public class GFG {
 
    int count = 0;
 
    // Driver code
    public static void main(String args[])
    {
 
        // Accessing static variable
        // by creating an instance
        // of the class
        GFG test = new GFG();
 
        test.count++;
        System.out.println(test.count);
    }
}
输出
1