简体   繁体   English

在2种不同类别的2种方法之间交换数据

[英]Exchanging data between 2 methods in 2 different classes

Im quite new to Java and this might be a basic doubt. 我对Java还是很陌生,这可能是一个基本的疑问。 But please help. 但是请帮忙。 I have a class as below: 我的课如下:

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];
}

I have another class: 我还有另一堂课:

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];
    }
}

So like you can see..there are 2 different classes, which have the same method, but receive different data. 就像您看到的那样。有2个不同的类,它们具有相同的方法,但是接收的数据不同。 I need to get an input from the user for the "String name" in DefFunctionHandler class, and I identify the given name with the name in the file that I have...then correlate it with other data in the method like funcgroup and func . 我需要从用户那里获得DefFunctionHandler类中“字符串名称”的DefFunctionHandler ,然后用我拥有的文件中的名称标识给定名称...然后将其与诸如funcgroupfunc类的方法中的其他数据相关联。 The same func is there in the other class too. 另一个类也有相同的func So I need to make a comparison between them to get the data in the other class like time, etc. 因此,我需要对它们进行比较,以获取其他类(​​例如时间等)中的数据。

So the data in the methods can be compared to the data structure in C...how do I implement such a structure in Java? 因此可以将方法中的数据与C中的数据结构进行比较...如何在Java中实现这种结构? I read that structs are similar to classes in Java. 我读到结构类似于Java中的类。 But in my case, I have the data in methods and not classes. 但就我而言,我将数据存储在方法而非类中。 Please tell me how to solve this problem. 请告诉我如何解决这个问题。

To Answer Your Original Question 回答您的原始问题

Long story short, you can't access method variables externally. 长话短说,您不能从外部访问方法变量。 What you want to do is make those variables fields within the class. 想要做的是使课堂内的那些变量字段 Putting them outside the method means they stick around after the method is done, and it means you can access them from outside. 将它们放在方法之外意味着在方法完成后它们仍然存在,这意味着您可以从外部访问它们。

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];
    }
}

Then you access them by creating getters and setters : 然后,通过创建gettersetter来访问它们:

public long getTime() {
    return time;
}
public void setTime(long t) {
    time = t;
}
// etc...

HOWEVER, Some Suggestions... 但是,一些建议...

Your code is... strange, to say the least. 至少可以说,您的代码很奇怪。 It's also very non-Java-like. 它也非常不像Java。 As much as possible, you should try to avoid having multiple overriding methods that need different data. 您应尽可能避免使用需要不同数据的多种覆盖方法。 Also, you normally want to initialize your fields in the constructor , not in some other method. 同样,您通常希望在构造函数中而不是其他方法中初始化字段

It's not clear how much of the code you have access to, but if you're able to rewrite the interface, I would definitely do so. 尚不清楚您可以访问多少代码,但是如果您能够重写接口,我肯定会这样做。 Object varargs in an interface is just weird. 接口中的Object varargs很奇怪。 The reason for using an interface is so that you can call an interface method with identical parameters and, regardless of the object type underneath, something useful will happen. 使用接口的原因是可以调用具有相同参数的接口方法,并且不管下面的对象类型如何,都会发生有用的事情。 It defeats the point of the interface to have two implementations of the same method require totally different arguments. 它破坏了接口的观点,使同一方法的两个实现需要完全不同的参数。 The following code demonstrates why this is: 以下代码演示了为什么这样做:

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

Much better to just make them different methods entirely.You know what variables you're expecting, so you should take advantage of that fact. 将它们完全设为不同的方法要好得多。您知道要使用什么变量,因此应该利用这一事实。 Your method signatures would be far better off looking something like this: 您的方法签名最好看起来像这样:

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
    }
}

As others have suggested, if the "real" method signatures are not identical, you shouldn't be using an interface. 正如其他人所建议的那样,如果“真实”方法签名不相同,则不应使用接口。 Better to use an abstract base class instead, to hold what little data is common between them: 最好改用抽象基类,以容纳它们之间的共同点:

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
}

Of course, if you set all the variables in the constructors, you may be able to add an abstract handle() method to the base class, since then that method should have the same signature, and take no arguments at all! 当然,如果您在构造函数中设置了所有变量,则可以向基类添加抽象的handle()方法,因为该方法应具有相同的签名,并且完全不带参数!


Final Result 最后结果

So if we pull together all the changes I've talked about-- moving the method variables into fields , using getters and setters , using useful method signatures , using constructors , and using a base class instead of a misleading interface, we end up with something like this: 因此,如果我们将我已经讨论过的所有更改放在一起-将方法变量移动到字段中 ,使用gettersetter 方法 ,使用有用的方法签名 ,使用构造 方法 ,并使用基类而不是误导性的接口,那么最终像这样的东西:

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();
    }
}

In order to make the variables class variables, all you have to do is move their declaration outside of the method. 为了使变量成为类变量,您要做的就是将它们的声明移到方法之外。 In other words, your code for the EnterLeaveHandler might look like this: 换句话说,您用于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];
        ...
    }
}

You need to restructure your objects to have proper constuctors and setters/getters 您需要重组对象以具有适当的构造函数和设置器/获取器

This gives the benefit of protecting all your private variables and forcing other classes to adhere to your classe's "contract" by only allowing them to access it's inner variables via those setters/getters and constructor. 这样可以保护所有私有变量,并仅允许其他类通过这些设置器/获取器和构造器访问其内部变量,从而使其他类遵守类的“契约”。 Now you just instantiate the object, then use ti's methods to manipulate it. 现在,您只需实例化对象,然后使用ti的方法对其进行操作。

Here is an example from your first example class: 这是您的第一个示例类的示例:

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);
    }
}

Create an abstract super class for your classes. 为您的类创建一个抽象超类。 Extend this with your classes and init the parameters in the handle call. 用您的类扩展它,并在handle调用中初始化参数。

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;
   } 
}

The best solution I could think of 1. is create a getter and setter 我能想到的最好的解决方案是创建一个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 http://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html

2.create a wrapper method to do the comparsion prior to calling the individual method. 2.在调用单个方法之前,创建一个包装器方法进行比较。

Hope this helps you. 希望这对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM