Java 保留类实例的替代方法

Java 保留类实例的替代方法,java,Java,我有一个对象,它本质上是一个数据结构,它的方法需要访问“Main”类的实例(这个类可以有多个实例)。我现在做的是在构造函数中传递一个主类的实例,但这似乎有点笨拙。我也可以在方法调用中传递一个主类的实例,但这似乎增加了太多的复杂性,我很可能也会遇到同样的问题,因为调用方法的并不总是主类 我不是在寻找静态方法/变量,因为我正在对主类中的实例变量进行更改 有没有更好的方法来实现这一点,而不必将实例存储在多个位置 示例代码: public class Main { public Main() {

我有一个对象,它本质上是一个数据结构,它的方法需要访问“Main”类的实例(这个类可以有多个实例)。我现在做的是在构造函数中传递一个主类的实例,但这似乎有点笨拙。我也可以在方法调用中传递一个主类的实例,但这似乎增加了太多的复杂性,我很可能也会遇到同样的问题,因为调用方法的并不总是主类

我不是在寻找静态方法/变量,因为我正在对主类中的实例变量进行更改

有没有更好的方法来实现这一点,而不必将实例存储在多个位置

示例代码:

public class Main {
    public Main() {
        Class1 class1 = new Class1(this);
        Class2 class2 = new Class2();

        class1.doSomething();
        class2.doSomething(this);
    }

    public void doSomethingElse() {
        // There is a point to this... I swear...
    }
}

public class Class1 {
    private Main instance;

    public Class1(Main instance) {
        this.instance = instance;
    }

    public void doSomething() {
        instance.doSomethingElse();
    }
}

public class Class2 {
    public void doSomething(Main instance) {
        instance.doSomethingElse();
    }
}

也许单例模式或此模式的扩展就是您所需要的?对象(Class1或Class2中的实例)将访问Main.getInstance()以接收主类的/an实例(可以扩展singleton模式以仅支持有限数量的实例,而不是仅支持一个实例)。

如果您担心内存使用或重新资源管理,考虑到即使您有50个data storge类的对象,您也只需要一个Main类的实例,并将这个实例发送给所有数据存储对象。然后,示例中的
Class1.instance
变量将指向与
Class49.instance
相同的
Main
实例。这就是指针的工作方式以及它们的优点


您可以让您的数据结构类扩展主类,但除此之外(不包括您希望的静态),没有办法将实例作为参数发送给构造函数或方法。

要判断哪一个更好,请始终查看代码读者期望的内容

首先是‘有’关系的问题。如果你说
Class1
总是对同一个
Main
实例感兴趣。在任何时候,这种连接都是有意义的(因此在任何时候
Class1
都可以明智地调用
Main
中的方法)。那么
Class1
是更好的选择

在其他情况下,您可以争辩:
Class2
根据传递的
Main
的任何实例提供服务。那么这是更好的选择


在您的示例中,
Class1
Class2
实例都是短期的。在这种情况下,我假设它们没有状态,我会将
Main
的实例传递给函数。这在功能上等同于静态方法,但是,通过在无状态对象的实例上使用它,您可以为将来的扩展和测试保留选项。我的一个扩展示例是,我后来为我的helper类添加了“设置”(
Class2
),这些设置在helper类的所有函数中都是活动的

如果您担心每次都必须传递主类实例(以及以后随着程序的增长可能传递的其他实例)的维护开销,那么您可能需要的是依赖注入框架(您目前正在做的是依赖项注入;依赖项注入框架旨在实现过程自动化)。Spring是最著名的,但也有其他的。只有当您希望项目变得越来越大时,它才值得(了解如何使用这样的框架涉及到相当大的开销),但它将简化确保所有对象都有对其所需内容的引用的任务。

这取决于您所追求的内容,但您可以使用内部类(非静态)。它有一个不可见的引用(Main.this),因此在资源方面没有区别,但您不必显式传递引用

    public class Main {
        public Main() {
            Class1 class1 = new Class1();
            class1.doSomething();
        }

        public void doSomethingElse() {
        }

        public class Class1 {
            public void doSomething() {
                doSomethingElse();
            }
        }
    }

存储对象实例的问题是什么?你需要一个对象的引用才能调用这个对象上的方法。没有办法。你不喜欢你拥有的东西有什么?你想对多个类的多个实例执行操作,而同步你访问的结构是不够的?购买时不要引用您需要访问的e实例?在多线程环境中,使线程局部无效?我不喜欢在类的每个实例中存储信息,对我来说这似乎有点浪费,但似乎是必要的。这是必要的,因为您需要对对象的引用才能对其调用方法。您意识到一个对象只有4个字节,对吗?有一些替代方法,比如使用一个更解耦的观察者/观察者模式,或者一个事件总线。但最终,你总是需要对对象的引用。在你遇到问题之前,不要担心浪费。编程就是为了清晰。除非你创建了数十亿个对象、引用甚至对象和你是你能拥有的最便宜的东西之一(比复制东西便宜得多).虽然Singleton模式可以实现问题所寻求的目标,但大多数人似乎认为他现在的做法更好。将实例传递给每一个需要它的对象,可以在未来可能发生的变化(例如)面前提供更大的灵活性需要两个实例,或者为了单元测试的目的允许通过双重测试,而不需要复杂的完整实现。我可能应该为这个问题添加更多的信息:对象很可能是相对较短的,并且存储在一个中等大小的数组中(几千个)它们很可能是不可变的,因为它被设计成线程安全的。Class1仍然适合这样做吗?对象的数量与您的数量无关。这两种解决方案都可以实现线程安全。由于
Class1
Class2
是不可变的,因此数据更改将对main进行,这需要