Java 在2个不同类中的2个方法之间交换数据
我对Java很陌生,这可能是一个基本的疑问。但是请帮忙。 我的课程如下:Java 在2个不同类中的2个方法之间交换数据,java,Java,我对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)
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
类中“字符串名称”的输入,并用我拥有的文件中的名称标识给定名称…然后将其与方法中的其他数据关联,如funcgroup
和func
。另一个类中也有相同的func
。因此,我需要对它们进行比较,以获得其他类中的数据,如时间等
因此,方法中的数据可以与C中的数据结构相比较……我如何在Java中实现这样的结构?我读到结构类似于Java中的类。但在我的例子中,数据是在方法中,而不是在类中。请告诉我如何解决这个问题 为了使变量成为类变量,您所要做的就是将它们的声明移到方法之外。换句话说,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];
...
}
}
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;
}
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();
}
}
回答你原来的问题
长话短说,您不能从外部访问方法变量。您要做的是将这些变量设置为类中的字段。将它们放在方法之外意味着它们在方法完成后仍然存在,这意味着您可以从外部访问它们
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。您应该尽可能避免使用需要不同数据的多个重写方法。此外,您通常希望在构造函数中初始化字段,而不是在其他方法中初始化字段 不清楚您可以访问多少代码,但是如果您能够重写接口,我肯定会这样做<代码>对象接口中的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 {
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];
...
}
}
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;
}
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();
}
}
正如其他人所建议的,如果“真实”方法签名不相同,则不应使用接口。最好使用抽象基类,以保存它们之间的少量公共数据:
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,使用有用的方法签名,使用构造函数,使用基类而不是误导性的接口,我们最终会得到如下结果:
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];
...
}
}
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;
}
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.就是创建一个getter和setter
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
2.在调用单个方法之前,创建一个包装器方法来进行比较
希望这对您有所帮助。您需要重新构造对象,使其具有适当的构造函数和setter/getter 这样做的好处是保护所有私有变量,并通过只允许其他类通过这些setter/getter和构造函数访问类的内部变量来强制其他类遵守类的“约定”。现在您只需实例化对象,然后使用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);
}
}
为类创建一个抽象的超类。使用您的类来扩展它,并初始化句柄调用中的参数
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;
}
}
这不是真正类似Java的代码。与具有对象数组的方法的接口?无论如何,我会将接口变成一个抽象类,并将公共变量移动到其中,然后为其创建一个equals(IOtFHandler)方法。这些方法是您的还是现有的方法?@fge这是我正在开发的Eclipse插件应用程序的一部分,这些方法由我使用接口定义。“我正在开发”--那就别这样开始编码了!它也是“反Java”的,我想说不要使用varargs(
Objects…args
),除非你真的不知道会传入多少个参数。在您的情况下,您需要4个arg,然后是5个arg。因此,您的程序应该通过适当的方法签名来反映这一点。方法签名应该告诉你什么进入了一个方法,什么出来了。。。使用varargs是不明确的(糟糕的编程习惯)。我在上面遇到的唯一问题是,该类是一个“处理程序”类,而不是在方法/类之间传输数据的DTO(数据传输对象)。理想情况下,应该有一个单独的DTO来封装需要共享的数据。作为OP的补充,一个类实例需要引用另一个类实例才能传递数据。varargs是一个糟糕的编程习惯,请更新您的帖子以显示正确的方法签名。我同意,SnakeDoc,但他正在实现的接口似乎需要对象。。。表单。@DavidChristo是的,但是一个永久记录显示这样的使用是不好的。同时,这也带来了一个问题。。。界面也应该重建得更好。由于接口的行为类似于契约执行器,因此它应该期望特定类型的参数的确切数量来获得它的