在这种情况下,静态函数和实例如何协同工作?

How Do Static Functions and Instances Work Together In This Case?

我正在努力学习 java,我正在尝试了解如何从一个 class 调用函数到另一个。我有两个 class,我将在下面 post。当我在 ToDo class 中调用 H2db.addItems() 以及在 H2db class 中调用 ToDo.menu() 时,我看到了 "Non-static method cannot be referenced from a static context"。谷歌搜索显示它与实例(?)有关,但我不确定那是什么意思。

Class待办事项:

package com.company;


import java.io.*;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.Scanner;

public class ToDo {
    //BufferedReader inputread = new BufferedReader(new InputStreamReader(System.in));
    Scanner inputread = new Scanner(System.in);
    ArrayList<String> toDoList = new ArrayList<String>();


    public void menu() {
        clearConsole();
        System.out.println("Welcome to the To-Do program.");
        System.out.println();
        System.out.println();
        System.out.println("Please select an option from the following menu, using the number.:");
        System.out.println("1- View To-Do List");
        System.out.println("2- Add Item To List");
        System.out.println("3- Remove Item From List");
        System.out.println("4- Save List");
        System.out.println("5- Load List");

        int userinput = inputread.nextInt();

        switch (userinput) {
            case 1:
                clearConsole();
                displayList(true);
                menu();
                break;
            case 2:
                clearConsole();
                H2db.addItems();
                break;
            case 3:
                clearConsole();
                deleteItem();
                break;
            case 4:
                clearConsole();
                try {
                    saveList();
                }
                catch(IOException e){
                    return;
                };

            case 5:
                clearConsole();
                try {
                    loadList();
                }
                catch(IOException e){
                    return;
                };

        }
    }

    public void clearConsole() {
        for (int i = 0; i < 25; i++) {
            System.out.println();
        }
    }


    public void addItem() {
        System.out.println("Please type the item to add to the To-Do List");
        //The skip gets over the leftover newline character
        inputread.skip("\n");
        String newItem = inputread.nextLine();
        toDoList.add(newItem);
        System.out.println("Your item has been added! Type any key and press Enter to continue");
        String discardMe = inputread.next();
        menu();
    }

    public void displayList(boolean finish) {

        if (toDoList.isEmpty()) {
            System.out.println("Add an activity.");

        } else {
            for (String listItem: toDoList) {
                System.out.println(listItem);
            }
        }
        if (finish) {
        System.out.println();
        System.out.println("This is your list. Type any key and press Enter to continue");
        String discardMe = inputread.next();
        }

    }

    public void deleteItem() {
        if (toDoList.isEmpty()) {
            System.out.println("For fuck's sake, add an activity.");
        } else {
            System.out.println("Please choose the number of the line you want to delete:");
            displayList(false);
            int userinput = inputread.nextInt();
            int listPos = userinput - 1;
            toDoList.remove(listPos);
            System.out.println("That item has been deleted. Type any key and press Enter to continue.");
            String discardMe = inputread.next();
        }
        menu();
    }

    public void saveList() throws IOException {
        System.out.println("Saving list...");
        PrintWriter writer = new PrintWriter("list.txt", "UTF-8");
        for (String listItem : toDoList) {
            writer.println(listItem);
        }
        writer.close();
        System.out.println("List saved! Type any key and press Enter to continue");
        String discardMe = inputread.next();
        menu();

    }

    public void loadList() throws IOException {
        System.out.println("Loading list...");

        File loadFile = new File("list.txt");
        Scanner scanner = new Scanner(loadFile);
        while (scanner.hasNext()) {
            String item = scanner.nextLine();
            toDoList.add(item);
        }
        System.out.println("List loaded! Type any key and press Enter to continue");
        String discardMe = inputread.next();
        menu();
        scanner.close();
    }
}

Class H2db:

package com.company;

import java.sql.*;
import java.util.ArrayList;
import java.util.Scanner;


public class H2db {
    Scanner inputread = new Scanner(System.in);
    ArrayList<String> toDoList = new ArrayList<String>();

    public void connect(){

        try {
            Class.forName("org.h2.Driver");
            Connection conn = DriverManager.getConnection("jdbc:h2:~/toDo", "user", "");
            Statement stat = conn.createStatement();

            stat.execute("CREATE TABLE IF NOT EXIST 'todo'(id int NOT NULL AUTO_INCREMENT primary key, item varchar(255))");
        }
        catch( Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public void addItems() {
        PreparedStatement addstat;

        try {
            Class.forName("org.h2.Driver");
            Connection conn = DriverManager.getConnection("jdbc:h2:~/toDo", "user", "");

            System.out.println("Please type the item to add to the To-Do List");
            inputread.skip("\n");
            String newItem = inputread.nextLine();
            addstat = conn.prepareStatement("INSERT INTO toDo (item)" +"VALUES (?)");
            addstat.setString(1, newItem);
            addstat.executeUpdate();

            System.out.println("Your item has been added! Type any key and press Enter to continue");
            String discardMe = inputread.next();
            ToDo.menu();
        }
        catch( Exception e) {
            System.out.println(e.getMessage());
        }

    }
}

任何帮助都会很棒,谢谢。我知道这只是知识上的差距,但我似乎无法理解这个概念到底叫什么。

看来您只需要 H2db 的一个实例。在这种情况下,您可以考虑使用 singleton 模式,但就像现在一样,您只需在适当的位置添加关键字 static 即可快速完成所有工作:

    static Scanner inputread = new Scanner(System.in);
    static ArrayList<String> toDoList = new ArrayList<String>();

    public static void connect(){

    public static void addItems() {

答案很简单。如果您想调用 class 名称的 H2db.addItems() ,则必须将 H2db class 中的 addItems() 方法声明为静态。或者

您可以创建 class H2db 的实例(对象)。

 H2db myObject = new H2db();
 myObject.addItems();

当您将方法或属性声明为静态时。然后就变成了classvariable/method。可以称为 H2db.addItems().

如果您不声明方法/属性为静态。然后它成为实例变量/方法。并且可以像上面的代码示例中提到的那样调用。那是按实例(对象)名称。

我认为您缺少面向对象编程的基础。 首先问问自己:class ToDo 代表哪个对象?查看您的代码,它是一个 GUIManager。

GUIManager 正常工作需要另一个对象能够将数据存储在名为 H2DBManager 的数据库中(当前为 class H2db)。 这意味着 GUIManager 必须在其构造函数中实例化一个 H2DBManager 即 h2DBManager 并在需要时使用其正常方法(非静态)。当 class H2DBManager 完成一项任务(即已完成在方法 addItems 中存储某些内容)时,控制流 returns 自动流向 class GUIManager,因此您无需显式调用 GUIManager来自 class H2DBManager 的操作(静态或非静态)。