【问题标题】:I need to make a variable accessible to the whole program in Java我需要使Java中的整个程序都可以访问一个变量
【发布时间】:2011-11-06 15:26:23
【问题描述】:

所以我的问题是这样的。我有一个名为Globals 的类,其中包含我在整个程序中需要的所有变量。它适用于字符串、整数和其他可以使用= 操作的东西。例如:

public class Globals {
   public static int globalInteger = 23;
   public static String globalString = "Hello, dude.";
   public static UserProfile globalUserProfile;
}

在项目的某个地方,我使用这些访问它们:

Globals.globalInteger += 17;

Globals.globalString = "Why, hello there!";

但是,我正在尝试将自己编写的课程设为全球性 (UserProfiles.class)。这个类不使用= 操作,因此,当我从其他地方访问它并得到java.lang.nullPointerException 时,它总是null。例如,如果我这样做(newProfile(String)UserProfiles.class 中的一个方法):

Globals.globalUserProfile.newProfile(profileName);

我收到java.lang.NullPointerException。如何让我的 UserProfile.class 变量在整个项目中都可以访问?提前致谢。

【问题讨论】:

  • 只是为了记录,“全球”的模式(尤其是+= 17 shudder)不是一个好的模式。见stackoverflow.com/questions/4646577/global-variables-in-java
  • 哦,我明白了。我对 Java 还是很陌生,但我仍然对一些基础知识感到困惑。我会读到的。谢谢。
  • 如果您编辑您的问题以解释 为什么 您要这样做,并给出一些您认为需要在全球范围内存储的值的真实示例,人们可以发表评论了解实现目标的更好方法。

标签: java global-variables


【解决方案1】:

编写一个所谓的工厂类,一步构建您的整个项目。

例子:

// a class which store configuration parameters - must be instanstiable!
public class Configuration {
   public Configuration() {
       // get configuration from Properties file, Resource Bundle etc.
   } 
}

public class A {
    private Configuration configuration;

    public A(Configuration configuration) {
        this.configuration = configuration;
    }
}

public class B {
    private Configuration configuration;
    private A a;

    public B(A a, Configuration configuration) {
        this.a = a;
        this.configuration = configuration;
    }
}

public class C {
    private Configuration configuration;
    private B b;

    public C(B b, Configuration configuration) {
        this.b = b;
        this.configuration = configuration;
    }
}

这里有 3 个类和一个配置类。它们都依赖于配置类,C依赖于B,B依赖于A。

如您所见,依赖关系由构造函数参数反映,这很好,因为依赖关系是显式的(也就是说,您现在需要哪些依赖关系而无需过多查看源代码)。

但是,你如何构建这个对象图呢?好吧,通过使用工厂类(这里甚至是静态工厂):

public class ApplicationFactory {
    // prevents instantiation
    private ApplicationFactory() {};

    public static C buildApplicationGraph() {
        // first, build the leaf objects (objects without other dependencies), here
        // Configuration
        Configuration configuration = new Configuration();

        // now, start injecting the dependencies needed
        // a only need a Configuration object
        A a = new A(configuration);

        // B needs a Configuration and an A object
        B b = new B(a, configuration);

        // we're done here        
        return new C(b, configuration);         
    }
}

如您所见,您正在自下而上构建对象图。所有依赖项都是显式的,并且您将构建过程与业务逻辑分开。

我们在这里所做的是构造函数依赖注入,即我们通过构造函数传入每个类所需的依赖项。为了创建所需的对象,我们编写了一个工厂。

最后,我们拥有轻量级类(这里没有构建工作)、显式依赖项(使用 Singleton 没有这些)和最大的灵活性(工厂甚至可以返回 C 的子类)。

编辑

另一个优点是您可以单独测试您的类,因为您可以轻松地模拟参数(例如,通过传入参数的子类)。

【讨论】:

    【解决方案2】:
    【解决方案3】:

    您可以在 Globals 类中默认实例化您的类:

    public static UserProfile globalUserProfile = new UserProfile();
    

    或者你必须在 UserProfile 类中声明一个工厂方法。

    【讨论】:

    • 我也建议使用 get 方法,以检查 globalUserProfile 是否为 null 并实例化它,而不是使用公共可访问变量。 getUserProfile() { return globalUserProfile != null ? globalUserProfile : (globalUserProfile = new UserProfile()); }
    猜你喜欢
    • 2019-12-22
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2011-07-09
    • 2016-03-11
    • 2017-01-20
    • 1970-01-01
    • 2021-05-19
    相关资源
    最近更新 更多