为什么Eclipse建议我使我的方法静态

时间:2013-11-06 13:10:59

标签: java eclipse methods static-methods

我从一个类调用一个方法,它给我一个错误,使该方法静态。我很困惑为什么,因为我问了这个问题What's the difference between a class variable and a parameter in a constructor?而我的理解是类变量是静态的。

患者类:

public  String  setOption(String option) throws IOException
{
        option = stdin.readLine();
        //stuff here
    return option;
}

患者管理系统:

public class PatientManagementSystem
{
    static BufferedReader stdin = new BufferedReader(new InputStreamReader(
            System.in));
    public static void main(String[] args) throws IOException
    {
        Patient.setOption(null);    
    }
}

错误:
enter image description here

我是将方法更改为静态还是创建局部变量?

9 个答案:

答案 0 :(得分:6)

根据您之前的问题,我认为可能没有完全挖掘局部变量的概念。在这种方法中:

public String setOption(String option) throws IOException
{
    option = stdin.readLine();
    return option;
}

option是一个局部变量。每次调用它时,都会将该变量的初始值作为参数传递给setOption方法(并且您碰巧忽略了该值),但是将详细信息排除在外,这与

相同
public String setOption() throws Exception
{
    String option = stdin.readLine();
    return option;
}

现在,局部变量与实例或类变量完全不同:它们仅在方法体内有效,并且仅在方法执行期间存在。考虑到这一点,让我们看看这段代码:

static BufferedReader stdin = new BufferedReader(new InputStreamReader(
        System.in));
public static void main(String[] args) throws IOException
{
    Patient.setOption(null);    
}

在这里,你基本上滥用了一个类变量stdin来处理应该是局部变量的东西:

public static void main(String[] args) throws IOException
{
    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
    Patient.setOption(null);    
}

关于方法调用的问题... setOption当前是实例方法,这意味着必须在实例的上下文中调用它。您按原样调用它,没有涉及Patient的实例。如果你继续走这条路,你将无法代表一个以上的病人,可能不是你的想法。因此,您希望保持方法不变并创建Patient的实例:

Patient p = new Patient();
p.setOption(...);

在您的整体设计中,不清楚setOption应该扮演什么角色,但是它使用静态stdin变量并不是一个好主意(我已经在上面创建了它)。您希望将从stdin读取的任何数据传递到setOption方法,从而将其与输入读取逻辑分离。

答案 1 :(得分:5)

您(可能)需要创建Patient类的对象。

Patient myPatient = new Patient();
myPatient.setOption(null);

很难知道你想用这些有限的信息做什么。我不知道你打算用Patient课程做什么,但我最好的猜测?考虑到您尝试使用setter命名约定调用方法,这样做是有道理的。

如果您不打算实例化一个对象并采用setOption static方法的路线,那么您应该更改方法名称。


通过更深入地解释你究竟想要完成什么(甚至不谈伪代码,只是一个非常抽象的想法,你想要做什么),更容易解释一下static在这里(以你的具体例子为准)以及你应该做什么等等。

答案 2 :(得分:3)

  

我是否将方法更改为静态或创建局部变量?

两者都可以。

如果您的方法不使用类变量,最好将其设置为静态,因此您不必为方法调用实例化类。

答案 3 :(得分:3)

何时制作静态与非静态的问题基于被建模的现实世界对象/概念。我们以此代码中的Patient对象为例。如果没有看到关于Patient的任何代码,那么Patient 以及代表的内容仍然很清楚。所以,最简单的是:

  • 如果您正在使用特定 Patient(让我们说Jane Doe)做某事,那么它不是静态的。它在Patient
  • 实例上运行
  • 如果您正在对Patient的概念采取某些措施,那么它就是静态的。

所以一些非静态操作可能是:

  • 更新Patient的名称
  • 从医院接纳/解除Patient
  • Patient转移到其他Doctor

所有这些都涉及特定的 Patient,它本来会在某处初始化:

var janeDoe = new Patient("Jane Doe");
// ...
janeDoe.TransferTo(doctorSmith);

我实际上在考虑Patient的一些静态方法时遇到了麻烦。静态方法最常见的示例可能是工厂方法,您可以在其中获得现有的PatientPatient的集合。类似的东西:

var janeDoe = Patient.Fetch("Jane Doe");

或:

var todaysPatients = Patient.Fetch(DateTime.Today);

各种辅助方法通常也是静态的,例如,Patient对象上可能接受MedicalRecord对象并将其转换为其他格式的方法。

但总体思路是一样的。如果您正在与对象的特定实例进行交互,那么您需要该对象的实例来表示该真实世界的概念。

答案 4 :(得分:2)

因为你直接调用那个方法而没有创建类的对象。

When to have static methods?

答案 5 :(得分:2)

要以静态方式调用方法,必须将其设为静态:

public static String  setOption(String option) throws IOException

但是在你的例子中,如果stdin不是Patient类的静态成员,那么它就无法工作。

总而言之,您可以在声明为静态时调用方法。在静态方法中,您只能访问类的静态成员。

答案 6 :(得分:2)

main method

中试试这个
Patient myPatient = new Patient();
myPatient.setOption(null);

答案 7 :(得分:2)

当我们打算将这些方法用作实用程序方法时,我们使用静态方法创建类,例如Integer类中的parseInt。因此要么修改方法

public static String  setOption(String option) throws IOException // STATIC
{
    option = stdin.readLine();
    //stuff here
    return option;
}

然后使用像

这样的方法
    Patient.setOption(null);    

OR 为患者实例化对象

    Patient obj = new Patient();
    obj.setOption(null);    

答案 8 :(得分:2)

在Java中,main方法很特别。这是代码的起点。可以从代码中的任何位置调用静态方法。因此实际上它不属于包含类。对于主要方法也是如此。

因此,您应该在main方法中构造对象,然后使用构造的实例的方法。如果你没有构建一个实例,那么你的ide会识别错误并建议你把它变成静态的。