如何在 Java 中的不同类之间共享数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4419810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:16:42  来源:igfitidea点击:

How to share data between separate classes in Java

javaoopclass-design

提问by f20k

What is the best way to share data between separate classes in Java? I have a bunch of variables that are used by different classes in separate files in different ways. Let me try to illustrate a simplified version of my problem:

在 Java 中的不同类之间共享数据的最佳方式是什么?我有一堆变量在不同的文件中以不同的方式被不同的类使用。让我尝试说明我的问题的简化版本:

This was my code before:

这是我之前的代码:

public class Top_Level_Class(){
    int x, y;

    // gets user input which changes x, y;
    public void main(){
       int p, q, r, s;
       // compute p, q, r, s
       doA(p,q,r);
       doB(q,r,s);
    }

    public void doA(int p, int q, int r){
       // do something that requires x,y and p, q, r
    }

    public void doB(int q, int r, int s){
       // does something else that requires x, y and q, r, s
    }
}

Now it looks something like this:

现在它看起来像这样:

public class Top_Level_Class(){
    int x, y;
    SomeClass1a a = new SomeClass1a();
    SomeClass1a b = new SomeClass1b();
    // gets user input which changes x, y;
    public void main(){
       int p, q, r, s;
       // compute p, q, r, s
       a.doA(p,q,r);
       b.doB(q,r,s);
    }

public class SomeClass1a() {  // in its own separate file
    public void doA(int p, int q, int r){
       // do something that requires x,y and p, q, r
    }
}


public class SomeClass1b() {  // in its own separate file
    public void doB(int q, int r, int s){
       // does something else that requires x, y and q, r, s
    }
}

So anyway, should I pass x and y each time (where x,y are variables stored in the helper class func) ?

所以无论如何,我应该每次都传递 x 和 y (其中 x,y 是存储在辅助类 func 中的变量)?

 a.set(x,y);
 a.doA(p,q,r);

My idea was to have a special container class where x and y are held. The top level class would have an instance of the container class and change x,y using the set methods.

我的想法是有一个特殊的容器类,其中包含 x 和 y。顶级类将拥有容器类的实例并使用 set 方法更改 x,y。

// in the top level class:
Container c = new Container(x,y);
a.setContainer(c);
b.setContainer(c);

My helper classes would also have an instance of the container and it would point to the same instance as in the top level. That way they access the same x,y as in the top level.

我的助手类也有一个容器实例,它指向与顶层相同的实例。这样他们就可以访问与顶层相同的 x,y。

I would like to know if I should

我想知道我是否应该

  • Use the container class
  • Load x,y each time into the subclasses
  • ?? Some better method ??
  • 使用容器类
  • 每次将 x,y 加载到子类中
  • ?? 一些更好的方法?

采纳答案by Andrea Sindico

I guess the answer to your question is the Design Pattern called Singleton. It basically allows you to get and exploits the same (and unique) instance of a class whenever you want in your system.

我想你的问题的答案是称为单例的设计模式。它基本上允许您在系统中随时获取和利用类的相同(且唯一)实例。

This is its implementation (please forgive possible syntax errors, I did not compile it):

这是它的实现(请原谅可能的语法错误,我没有编译它):

class Container{

  //eventually provides setters and getters
  public float x;
  public float y;
  //------------

  private static Container instance = null;
  private void Container(){

  }
  public static Container getInstance(){
    if(instance==null){
       instance = new Container();
      }
      return instance;
  }
}

then if elsewhere in your code you import the Container you can write for example

然后,如果在您的代码中的其他地方导入了您可以编写的容器,例如

Container.getInstance().x = 3;
temp = Container.getInstance().x;

and you will affect the attributes of the unique container instance you have in your system

并且您将影响您系统中的唯一容器实例的属性

In many cases it is however better to use the Dependency Injection pattern as it reduces the coupling between different components.

然而,在许多情况下,最好使用依赖注入模式,因为它减少了不同组件之间的耦合。

回答by AlanObject

I am having a hard time seeing what your problem is -- why don't you want to pass x an y as a parameter?

我很难看出你的问题是什么——你为什么不想将 x 和 y 作为参数传递?

Oh, well. Assuming you don't, I don't see a need for a new container class. Do it this way:

那好吧。假设您没有,我认为不需要新的容器类。这样做:

public class SubClass1a() {  // in its own separate file
    public void doA(Top_Level_Class caller, int p, int q, int r){
       // do something that requires x,y and p, q, r
       // **to get x use the expression term caller.getX() and caller.getY()**
    }
}

Of course you need to add the public getter methods getX() and getY() to Top_Level_Class.

当然,您需要将公共 getter 方法 getX() 和 getY() 添加到 Top_Level_Class。

If you do not want SubClass1a to be dependent on Top_Level_Class then you could create an interface that provides access to the variables.

如果您不希望 SubClass1a 依赖于 Top_Level_Class,那么您可以创建一个接口来提供对变量的访问。

回答by Raskolnikov

Blockquote The main reason I didn't want to pass x,y each time is because I have several functions in several SubClasses that each use (x,y, z, etc) and it didnt seem right to pass in like 6-8 variables each time I call a function. The sub classes used to be dependent, but I'm trying to take them out of the file so they can be used in a different project. Blockquote

Blockquote 我不想每次都传递 x,y 的主要原因是因为我在几个子类中有几个函数,每个子类都使用(x,y,z 等),并且像 6-8 个变量一样传递似乎不正确每次我调用一个函数。子类曾经是依赖的,但我试图将它们从文件中取出,以便它们可以在不同的项目中使用。块引用

If this is the case then you are better off abstracting your variables out to a container class. If every instance of these no-longer-dependent classes is going to use a large subset of these variables then it makes sense to have them all in one instance. Variables that are logically related should be found in the same place. Your approach should be something like:

如果是这种情况,那么最好将变量抽象到容器类中。如果这些不再依赖的类的每个实例都将使用这些变量的很大一部分,那么将它们全部放在一个实例中是有意义的。逻辑上相关的变量应该在同一个地方找到。你的方法应该是这样的:

public class Top_Level_Class(){
Container container = new Container(x, y, p, q, r, s);
SubClass1a a = new SubClass1a(container);
SubClass1a b = new SubClass1b(container);
// gets user input which changes x, y using container's getters and setters
public void main(){
   // compute and set p, q, r, s
   a.doA();
   b.doB();
}

public class SubClass1a(Container c) {  // in its own separate file
    public void doA(c.getX, c.getY, c.getP, c.getQ, c.getR){
       // do something that requires x, y, p, q, and r
    }
}

public class SubClass1b(Container c) {  // in its own separate file

    public void doB(c.getX, c.getY, c.getQ, c.getR, c.getS){
       // does something else that requires x, y, q, r, and s
    }
}

public class Container(x, y, p, q, r, s) {
    //getters and setters for all variables
}

This keeps you from getting into a variable passing spaghetti-code situation, and when you want to use just one or two of these classes later your code is modular enough to port with just those classes and your container.

这可以防止您陷入变量传递意大利面条式代码的情况,并且当您以后只想使用这些类中的一两个时,您的代码足够模块化,可以仅移植这些类和您的容器。

回答by Armand

This question is a bit mad - the code in the question won't compile.

这个问题有点疯狂 - 问题中的代码无法编译。

public class Main {
    public static void main(String... args) {
        MutableDataContainer m = new MutableDataContainer();
        ImmutableDataContainer i = computeImmutableData();
        new ADoer().doA(m, i);
        new BDoer().doB(m, i);
    }
    ...
}

class MutableDataContainer {
    private int x, y;
    ... // getters and setters below
}

class ImmutableDataContainer {
    private final int p, q, r, s;
    ... // getters below
}

You'll need to define ADoerand BDoeras well.

您还需要定义ADoerBDoer