回答您的原始问题
长话短说,您不能从外部访问方法变量。您要做的是在类中创建这些变量字段。将它们放在方法之外意味着它们在方法完成后仍然存在,这意味着您可以从外部访问它们。
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];
}
}
然后通过创建getter和setter来访问它们:
public long getTime() {
return time;
}
public void setTime(long t) {
time = t;
}
// etc...
但是,一些建议...
至少可以说,您的代码很奇怪。它也非常不像Java。您应该尽可能避免使用需要不同数据的多个覆盖方法。此外,您通常希望在构造函数中初始化字段,而不是在其他方法中。
目前尚不清楚您可以访问多少代码,但如果您能够重写界面,我肯定会这样做。Object
界面中的可变参数很奇怪。使用接口的原因是您可以调用具有相同参数的接口方法,并且无论下面的对象类型如何,都会发生一些有用的事情。它违背了接口的要点,即同一方法的两个实现需要完全不同的参数。以下代码演示了为什么会这样:
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()
在基类中添加一个抽象方法,因为那个方法应该有相同的签名,并且根本不带参数!
最后结果
因此,如果我们将我讨论过的所有更改汇总在一起——将方法变量移动到字段中,使用getter和setter,使用有用的方法签名,使用构造函数,以及使用基类而不是误导性接口,我们最终会得到像这样的东西:
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();
}
}