【问题标题】:Referencing a non static array list in a static environment?在静态环境中引用非静态数组列表?
【发布时间】:2019-02-19 11:47:04
【问题描述】:

我刚开始学习Java一个月左右,现在遇到“无法从静态上下文引用非静态变量studentList”的问题。我试图从 main 中使用一个单独的方法来填充学生列表,而不是从 addStudent 为每个学生复制粘贴内容;但我无法获得写入 ArrayList 的方法。 (错误:(14, 27) java: 不能从静态上下文引用非静态变量 studentList)。我了解数组不是静态的,因为它的大小未定义,但我怎样才能让它按原样工作?有没有更好的方法?我可以让数组成为主要方法的一部分,然后将它传递给 addStudent,如果可以的话怎么办?

import java.util.ArrayList;

public class Main {
    ArrayList<Student> studentList = new ArrayList<>();

    public static void main(String []args) {
        addStudent("Adam", "Goldsmith", 70, 50);
        addStudent("John", "Smith", 20, 40);
        addStudent("Lewis", "Peterson", 90, 85);

        for (Student obj: studentList){
            System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
        }
    }

    public static void addStudent(String forename, String surname, int coursework, int test) {
        Student newStudent = new Student(forename, surname);
        newStudent.setForename(forename);
        newStudent.setSurname(surname);
        newStudent.averageMark(70, 65);

        studentList.add(newStudent);
    }

}

和我的“学生”班:

public class Student {
    String studentForename;
    String studentSurname;

    public Student(String studentForename, String studentSurname) {
        setForename(studentForename);
        setSurname(studentSurname);
    }

    // Set forename.
    public void setForename(String newForename) {studentForename = newForename;}

    // Set surname.
    public void setSurname(String newSurname) {studentSurname = newSurname;}

    //
    public double averageMark(int courseworkMark, int testMark){
        return (courseworkMark+testMark)/2;
    }

    // Grab the forename
    public String grabForename(){
        return studentForename;
    }

    // Grab the surname
    public String grabSurname(){
        return studentSurname;
    }

    // Grab the full name
    public String grabFullName(){
        return studentForename + "" + studentSurname;
    }
}

【问题讨论】:

  • 非静态变量属于你的实例(每次你使用new Student()你创建一个)。静态变量属于您的类,这意味着它们在所有实例之间共享。您不能在静态上下文中使用实例变量,因为您没有实际的实例开始。如果您要通过其参数将一个传递给该方法,那么它将起作用
  • TLDR:让您的 studentList 变量 static 使其工作

标签: java arraylist static


【解决方案1】:

您的代码应如下所示,尤其是您使用 java encapsulation 的 Student 类

public class Student {

   private String studentForename;
   private String studentSurname;
   private int courseworkMark;
   private int testMark;

    public Student(String studentForename, String studentSurname, int courseworkMark, int testMark) {
        this.studentForename = studentForename;
        this.studentSurname = studentSurname;
        this.courseworkMark = courseworkMark;
        this.testMark = testMark;
    }   
    public void setStudentForename(String studentForename) {
        this.studentForename = studentForename;
    }
    public String getStudentSurname() {
        return studentSurname;
    }
    public void setStudentSurname(String studentSurname) {
        this.studentSurname = studentSurname;
    }
    public String getStudentForename() {
        return studentForename;
    }  
    public double averageMark(){
        return (this.courseworkMark + this.testMark)/2;
    }
    public String grabFullName(){
        return studentForename + " " + studentSurname;
    }
}

然后通过您的 Main 类进行测试:

public class Main {    
    public static void main(String []args) {
        ArrayList<Student> studentList = new ArrayList<>();
        studentList.add(new Student("Adam", "Goldsmith", 70, 50));
        studentList.add(new Student("John", "Smith", 20, 40));
        studentList.add(new Student("Lewis", "Peterson", 90, 85));

        for (Student obj: studentList){
            System.out.println("Name: " + obj.getStudentForename() + " "+ obj.getStudentSurname());
        }
    }
}

【讨论】:

    【解决方案2】:
    import java.util.ArrayList;
    
    public class Main {
        static ArrayList<Student> studentList = new ArrayList<>();
    
        public static void main(String []args) {
            addStudent("Adam", "Goldsmith", 70, 50);
            addStudent("John", "Smith", 20, 40);
            addStudent("Lewis", "Peterson", 90, 85);
    
            for (Student obj: studentList){
                System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
            }
        }
    
        public static void addStudent(String forename, String surname, int coursework, int test) {
            Student newStudent = new Student(forename, surname);
            newStudent.setForename(forename);
            newStudent.setSurname(surname);
            newStudent.averageMark(70, 65);
    
            studentList.add(newStudent);
        }
    
    }
    

    这不是由于未定义的大小,而是因为您试图在没有从静态方法创建对象的情况下访问它。
    所以只要在它之前写静态就行了。

    【讨论】:

      【解决方案3】:

      认为上面的答案回答了你的问题,但是关于 java 中静态与非静态修饰符的几句话

      静态方法的特点

      • 使用类 (className.methodName) 调用静态方法,而不是实例引用 (new instanceOfClass = class; instanceOfClass.methodName。)
      • 静态方法不能使用非静态实例变量:静态方法不能引用类的任何实例变量。静态方法不知道要使用哪个实例的变量值。
      • 静态方法不能调用非静态方法:非静态方法通常使用实例变量状态来影响它们的行为。静态方法看不到实例变量的状态,因此如果您尝试从静态方法调用非静态方法,无论该非静态方法是否使用实例变量,编译器都会报错。​​

      非静态方法

      • 非静态方法的名称前没有关键字static。

      • 非静态方法属于类的对象,您必须创建类的实例才能访问它。

      • 非静态方法可以访问任何静态方法和任何静态变量,而无需创建类的实例。

      因此您最好考虑是否需要将 studentList 定义为静态或否,以及是否相应地修改您的代码。

      附:以上文字取自here

      【讨论】:

        【解决方案4】:

        静态(全局,类级别)和非静态(该类的实例,对象)之间的区别很重要。

        通过new Main() 创建一个对象允许对该对象及其字段进行操作。

        静态 void main(String[]) 是应用程序的单一入口点。

        在 main 中,您只能访问静态字段和静态方法。所以很麻烦。

        package srivastava.arpit; // In a directory path srivastava/arpit/
        
        import java.util.ArrayList;
        
        public class Main {
        
            private ArrayList studentList = new ArrayList<>();
        
            public static void main(String []args) {
                Main main = new Main();
                main.execute();
            }
        
            private void execute() {
                addStudent("Adam", "Goldsmith", 70, 50);
                addStudent("John", "Smith", 20, 40);
                addStudent("Lewis", "Peterson", 90, 85);
        
                for (Student obj: studentList){
                    System.out.println("Name: " + obj.studentForename + " "+ obj.studentSurname);
                }
            }
        
            public void addStudent(String forename, String surname, int coursework, int test) {
                Student newStudent = new Student(forename, surname);
                newStudent.setForename(forename);
                newStudent.setSurname(surname);
                newStudent.averageMark(70, 65);
        
                studentList.add(newStudent);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多