【问题标题】:non static variable name cannot be referenced from a static context [duplicate]不能从静态上下文中引用非静态变量名[重复]
【发布时间】:2011-05-12 17:19:11
【问题描述】:
class Singer
{
 String name;
 String album;

 public Singer(){
  name="Whitney Houson";
  album="Latest Releases";
 }

 public static void main(String[] args) 
 {
  System.out.println("Name of the singer is "+name);
  System.out.println("Album Information stored for "+album);

 }
}

当我运行这段代码时,我发现了一个错误,指出不能从静态上下文中引用非静态变量名

【问题讨论】:

    标签: java


    【解决方案1】:

    这是因为变量name和album在主程序中不存在,因为它是静态的,这意味着它不能访问实例级成员。您将需要一个 Singer 类的实例,如下所示:

    public static void main(String[] args) {
     Singer s = new Singer();
     System.out.println("Name of the singer is " + s.name);
     System.out.println("Album information stored for " + s.album);
    }
    

    但是,除非您使用公共访问修饰符声明您的姓名/专辑成员,否则上述代码将无法编译。我建议为每个成员(getName()、getAlbum() 等)编写一个 getter,以便从封装中受益。像这样:

    class Singer {
     private String name;
     private String album;
    
     public Singer() {
        this.name = "Whitney Houston";
        this.album = "Latest Releases";
     }
    
     public String getName() {
         return this.name;
     }
    
     public String getAlbum() {
         return this.album;
     }
    
     public static void main(String[] args) {
         Singer s = new Singer();
         System.out.println("Name of the singer is " + s.getName());
         System.out.println("Album information stored for " + s.getAlbum());
    
     }
    
    }
    

    另一种选择是将名称和专辑声明为静态,然后您可以按照您最初想要的方式引用它们。

    【讨论】:

    • ... + s.name); ... + s.album);
    • 顺便说一句,如果名称是私有的,因为main 也属于Singer,所以上面的代码将编译并运行良好。
    【解决方案2】:

    一个非静态成员或类需要被实例化才能存在。那么,从静态成员访问非静态成员或对象并不能保证该成员或对象被实例化,那么访问它是不可能的。

    您需要在静态上下文中创建非静态对象的实例才能创建它。

    class Singer {
        String name;
        String album;
    
        // You will need the following to make your code compile, 
        // and the call to these getters within your 'main' function.
        public getName() {
            return name;
        }
    
        public getAlbum() {
            return album;
        }
    
        public Singer() {
            name="Whitney Houson";
            album="Latest Releases";
        }
    
    }
    
    public static void main(String[] args)  {
        Singer singer = new Singer();
        System.out.println("Name of the singer is " + singer.getName());
        System.out.println("Album Information stored for " + singer.getAlbum());
    }
    

    这样,您将Singer 对象的实例化包含到一个静态对象中,从而确保在访问它之前正确实例化它。

    【讨论】:

      【解决方案3】:

      Main 是一个静态方法。如果不引用类的实例,就无法从静态方法访问实例变量(在类中定义但未标记为静态的变量)。

      public static void main(String[] args) 
      {
         Singer singer = new Singer();
         System.out.println("Name of the singer is " + singer.name);
         System.out.println("Album Information stored for " + singer.album);
      }
      

      【讨论】:

      • 当我编译此代码时没有发生错误,但是当我运行此代码时会给出一个错误,类似于线程“main”java.lang.NoClassDefFoundError: Singer 中的异常
      【解决方案4】:

      Chris Hutchinson 提到了一个选项。另一种是将它们声明为静态的。

      main 是一个静态方法。所以名称和专辑必须声明为静态。

      private static String name;
      private static String album;
      

      【讨论】:

        【解决方案5】:

        为了进一步扩展 Chris 的回答,从技术上讲,您可以拥有尽可能多的 Singer 类实例,只要您的内存可以支持,但只有一个 main 函数实例正在运行。这意味着尝试从静态函数访问这些变量意味着它不知道应该访问哪个变量实例,因此会出现错误。

        您可以将变量设置为 main 函数的局部变量,但这可能会破坏程序的目的,因为逻辑会规定可以有多个歌手(很可能)。更好的攻击计划是创建一个包含主函数的通用类,然后在该类(或其他地方)中创建一个 Singer 类,并在您的主函数中实例化该类的 X 个实例,然后从那里开始。

        【讨论】:

          猜你喜欢
          • 2013-12-02
          • 2013-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-17
          • 2011-11-30
          相关资源
          最近更新 更多