我从一个类调用一个方法,它给我一个错误,使该方法静态。我很困惑为什么,因为我问了这个问题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);
}
}
错误:
我是将方法更改为静态还是创建局部变量?
答案 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
的一些静态方法时遇到了麻烦。静态方法最常见的示例可能是工厂方法,您可以在其中获得现有的Patient
或Patient
的集合。类似的东西:
var janeDoe = Patient.Fetch("Jane Doe");
或:
var todaysPatients = Patient.Fetch(DateTime.Today);
各种辅助方法通常也是静态的,例如,Patient
对象上可能接受MedicalRecord
对象并将其转换为其他格式的方法。
但总体思路是一样的。如果您正在与对象的特定实例进行交互,那么您需要该对象的实例来表示该真实世界的概念。
答案 4 :(得分:2)
因为你直接调用那个方法而没有创建类的对象。
答案 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会识别错误并建议你把它变成静态的。