我对Java很新,这可能是一个基本的疑问。但请帮忙。 我有一个课程如下:
public class EnterLeaveHandler implements IOtfHandler {
public void handle(java.lang.Object ... args) {
long time = (Long) args[0];
int func = (Integer) args[1];
int cpuid = (Integer) args[2];
int source = (Integer) args[3];
}
我有另一个班级:
public class DefFunctionHandler implements IOtfHandler {
public void handle(Object... args) {
int stream = (Integer) args[0];
int func = (Integer) args[1];
String name = (String) args[2];
int funcgroup = (Integer) args[3];
int source = (Integer) args[4];
}
}
所以你可以看到..有两个不同的类,它们有相同的方法,但接收不同的数据。我需要从用户那里获得DefFunctionHandler
类中“String name”的输入,并且我在文件中标识给定的名称,然后将其与方法中的其他数据相关联例如funcgroup
和func
。另一个类中也存在相同的func
。所以我需要在它们之间进行比较,以获得其他类中的数据,如时间等。
因此,方法中的数据可以与C中的数据结构进行比较......如何在Java中实现这样的结构?我读到结构类似于Java中的类。但在我的情况下,我有方法而不是类的数据。请告诉我如何解决这个问题。
答案 0 :(得分:3)
简而言之,您无法从外部访问方法变量。您希望做的是在类中添加字段变量。将它们放在方法之外意味着它们会在方法完成后继续存在,这意味着您可以从外部访问它们。
public class EnterLeaveHandler implements IOtfHandler {
private long time;
private int func;
private int cpuid;
private int source;
// Please don't use varargs like this; read the whole answer!!
public void handle(Object ... args) {
time = (Long) args[0];
func = (Integer) args[1];
cpuid = (Integer) args[2];
source = (Integer) args[3];
}
}
然后您可以通过创建 getters 和 setters 来访问它们:
public long getTime() {
return time;
}
public void setTime(long t) {
time = t;
}
// etc...
你的代码......奇怪,至少可以说。它也非常类似Java。尽可能地,您应该尽量避免使用需要不同数据的多个重写方法。此外,您通常希望在构造函数中初始化字段,而不是在其他方法中。
目前尚不清楚您可以访问多少代码,但如果您能够重写界面,我绝对会这样做。界面中的Object
varargs很奇怪。使用接口的原因是您可以使用相同的参数调用接口方法,并且无论下面的对象类型如何,都会发生一些有用的事情。它违背了接口的要点,让同一方法的两个实现需要完全不同的参数。以下代码说明了原因:
IOtfHandler h1 = new EnterLeaveHandler();
IOtfHandler h2 = new DefFunctionHandler();
h1.handle(0, 0, 0, 0);
h2.handle(0, 0, 0, 0); // Crashes with ClassCastException!! :(
// And would also crash two lines later with ArrayIndexOutOfBoundsException
好多了让他们完全不同的方法。你知道你期待的变量,所以你应该利用这个事实。看起来像这样的方法签名会好得多:
public class EnterLeaveHandler implements IOtfHandler {
public void handle(long time, int func, int cpuid, int source) {
// Do things with your shiny new variables
}
public class DefFunctionHandler implements IOtfHandler {
public void handle(int stream, int func, String name, int funcgroup, int source) {
// Do things with your shiny new variables
}
}
正如其他人所说,如果"真实"方法签名不相同,您不应该使用接口。最好使用抽象基类来保存它们之间常见的小数据:
abstract class IOtfHandler {
private int source;
private int func;
public void setSource(int source) {
this.source = source;
}
// etc
}
class EnterLeaverHandler extends IOtfHandler {
private long time;
// etc
}
class DefFunctionHandler extends IOtfHandler {
private String name;
// etc
}
当然,如果在构造函数中设置所有变量,则可以向基类添加抽象handle()
方法,因为那时该方法应该具有相同的签名,并且不需要参数所有!
因此,如果我们将我讨论过的所有更改汇总到一起 - 将方法变量移动到字段,使用 getters 和 setters ,使用有用的方法签名,使用构造函数,并使用基类而不是误导性的接口,我们最终得到这样的东西:
abstract class IOtfHandler {
private int source;
private int func;
public void setSource(int source) {
this.source = source;
}
public int getSource() {
return source;
}
public void setFunc(int func) {
this.func = func;
}
public int getFunc() {
return func;
}
// abstract handle method
abstract public void handle();
}
class EnterLeaverHandler extends IOtfHandler {
private long time;
private int cpuid;
// getters and setters
public void setTime(long time) {
this.time = time;
}
public long getTime() {
return time;
}
public void setCpuId(int cpuid) {
this.cpuid = cpuid;
}
public int getCpuId() {
return cpuid;
}
// constructor
public EnterLeaverHandler(long time, int cpuid, int source, int func) {
setTime(time);
setCpuId(cpuid);
setSource(source);
setFunc(func);
}
// handle method
public void handle() {
System.out.println("EnterLeaverHandler.handle()");
// Do whatever class-specific handling you might want to do in here.
}
}
class DefFunctionHandler extends IOtfHandler {
private String name;
private int funcGroup;
private int stream;
// getters and setters
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setFuncGroup(int funcGroup) {
this.funcGroup = funcGroup;
}
public int getFuncGroup() {
return funcGroup;
}
public void setStream(int stream) {
this.stream = stream;
}
public int getStream() {
return stream;
}
// constructor
public DefFunctionHandler(String name, int funcGroup, int stream, int source, int func) {
setName(name);
setFuncGroup(funcGroup);
setStream(stream);
setSource(source);
setFunc(func);
}
// handle method
public void handle() {
System.out.println("DefFunctionHandler.handle()");
// Do whatever class-specific handling you might want to do in here.
}
}
public class Main {
public static void main(String[] args) {
IOtfHandler h1 = new DefFunctionHandler("name", 0, 0, 0, 0);
IOtfHandler h2 = new EnterLeaverHandler(0, 0, 0, 0);
h1.handle();
h2.handle();
}
}
答案 1 :(得分:0)
为了使变量成为类变量,您所要做的就是将它们的声明移到方法之外。换句话说,您的EnterLeaveHandler代码可能如下所示:
public class EnterLeaveHandler implements IOtfHandler {
long time;
int func;
int cpuid;
int source;
public void handle(java.lang.Object ... args) {
time = (Long) args[0];
func = (Integer) args[1];
cpuid = (Integer) args[2];
source = (Integer) args[3];
...
}
}
答案 2 :(得分:0)
您需要重新构建对象以使用适当的构造函数和setter / getters
这样可以保护所有私有变量,并强制其他类遵守classe的“契约”,只允许它们通过setter / getters和constructor访问它的内部变量。现在你只是实例化对象,然后用ti的方法来操作它。
以下是您的第一个示例类的示例:
public class EnterLeaveHandler implements IOtfHandler {
private long time;
private int func, cpuid, source;
public EnterLeavehandler(long time, int func, int cpuid, int source) {
this.time = time;
this.func = func;
this.cpuid = cpuid;
this.source = souce;
}
public long getTime() {
return this.time;
}
public void setTime(long time) {
this.time = time;
}
public int getFunc() {
return this.func;
}
public void setFunc(int func) {
this.func = func;
}
public int getCPUID() {
return this.cpuid;
}
public void setCPUID(int cpuid) {
this.cpuid = cpuid;
}
public int getSource() {
return this.source;
}
public void setSource(int source) {
this.source = source;
}
public void handle(long t, int f, int c, int s) {
this.setTime(t);
this.setFunc(f);
this.setCPUID(c);
this.setSource(s);
}
}
答案 3 :(得分:0)
为您的类创建一个抽象超类。使用类扩展它并在句柄调用中初始化参数。
public abstract class AbstarctFunctionHandler implements IOtfHandler {
long time;
int func;
int cpuid;
int source
//add getters and setters, if you fancy
public boolean equals(AbstarctFunctionHandler obj){
//compare variables
return true;
}
}
答案 4 :(得分:-2)
我能想到的最好的解决方案 1.创建一个getter和setter
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
http://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html
2.在调用单个方法之前,创建一个包装方法来进行比较。
希望这会对你有所帮助。