我需要在Java中使整个程序可以访问变量

时间:2011-11-06 15:26:24

标签: java global-variables

所以我的问题是这个。我有一个名为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)。这个类不使用=操作,因此,当我从其他地方访问它时,它总是null,我得到java.lang.nullPointerException。例如,如果我这样做(newProfile(String)UserProfiles.class内的方法):

Globals.globalUserProfile.newProfile(profileName);

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

4 个答案:

答案 0 :(得分:4)

答案 1 :(得分:4)

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

示例:

// 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 :(得分:2)

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

public static UserProfile globalUserProfile = new UserProfile();

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

答案 3 :(得分:0)

在这里,和大多数地方一样,我会避免使用Singleton模式。相反,你应养成使用依赖注入的习惯 - 用英语传递"全局类的实例"到需要它的班级。在实践中,这可以通过要求全球级"强制执行。在初始化任何其他需要它的类时作为参数传递。

在最近的一个项目中,我需要玩家知道所有怪物的位置,怪物知道所有玩家的位置,以及射击以了解所有玩家和怪物的位置。我将所有这些放在一个游戏对象中#34;类和所需的玩家,怪物和镜头在初始化时传递实例。实施比单身人士需要更多的时间,但这意味着全球课程不会在你不期望或想要的地方被访问。