开发者

Java: how to have global values inside a class?

I want less methods. I want a common global TestClass from which I could use any of its value inside the class.

import java.util.*;
import java.io.*;

public class TestClass {
        TestClass(String hello){
                String hallo = hello;
                String halloSecond = "Saluto!";
        }
        public static void main(String[] args) {
                TestClass test = new TestClass("Tjena!");
                System.out.println("I want "Tjena!": " + test.hallo);
                TestClass testSecond = new TestClass("1");
                System.out.println("I want Saluto!:" + test.halloSecond);
                System.out.println("I want Saluto!:" + testSecond.halloSecond);

                // How can I get glob.vars开发者_开发技巧 like the "Saluto!"?
        }
}

[Clarification Needed] I cannot understand the no-use of GLOB.VARS. Please, see the code belowe where you cannot access the GLOB.VARS without an instance, hence the error. If I quarantee no malicious code can make an instance, is there any problem in using GLOB.vars?

$ javac TestClass.java 
TestClass.java:19: non-static variable hallo cannot be referenced from a static context
  System.out.println("It did not get to the GLOB.VAR: " + hallo);
                                             ^
1 error
$ cat TestClass.java 
import java.util.*;
import java.io.*;

public class TestClass {
        public String hallo;
        public String halloSecond;

        TestClass(String hello){
                hallo = hello;
                halloSecond = "Saluto!";
        }
        public static void main(String[] args) {
                TestClass test = new TestClass("Tjena!");
      System.out.println("It did not get to the GLOB.VAR" + hallo);
        }
}


I want less methods.

You shouldn't. Methods should not be measured by count or size. They should exist if they have a separate responsibility.

I want a common global TestClass from which I could use any of its value inside the class.

This doesn't make much sense. I guess you need instance variables

 private String hello;
 private String helloSecond;

 TestClass(String hello){
        hallo = hello;
        halloSecond = "Saluto!";
 }

 public String getHello() { return hello; }
 public String getHelloSecond() { return helloSecond; }

How to have global values inside a class?

global variables can be achieved by defining them static:

public static String var;

But using these is a very bad practice. You must not use them.


Global variables are generally considered a Very Bad Idea. Yes, it can be difficult to design your classes so that every class contains all (or most) of the variables it needs to do its work. But it's much more difficult to deal with code that's based on global variables (Mainly because it becomes very hard to predict what effects changes in one part of the code will have on the rest of it).


I guess you are looking for something like this:

public class TestClass {
    public final String hallo;
    public static final String halloSecond = "Saluto!";

    TestClass(String hello){
        String hallo = hello;
    }

    public static void main(String[] args) {
        TestClass test = new TestClass("Tjena!");
        System.out.println("I want "Tjena!": " + test.hallo);
        TestClass testSecond = new TestClass("1");
        System.out.println("I want Saluto!:" + test.halloSecond);
        System.out.println("I want Saluto!:" + testSecond.halloSecond);
    }
}

The value of hallo is set in each instance of TestClass. The value of halloSecond is a constant, shared by all instances of the class and visible for the whole app. Note that with this code your IDE/compiler probably gives you a warning upon test.halloSecond - it should be qualified by the class name, like TestClass.halloSecond, rather than an instance name.

Update on global variables: the main problem with global variables is that they make the code

  • harder to understand - if a method uses global variables, you can't see simply from its signature what data is it actually manipulating
  • harder to test - same method is difficult to test isolated in unit tests, as you have to (re)set all global variables it depends on to the desired state before each unit test
  • harder to maintain - global variables create dependencies, which easily make the code into a tangled mess where everything depends on everything else

In Java everything is inside a class, so you can't have "classic" global variables like in C/C++. However, a public static data member is still in fact a global variable.

Note that the code sample above, halloSecond is a global constant, not a variable (as it is declared final and is immutable), which alleviates much of these problems (except maybe the dependency issue).


import java.util.*;
import java.io.*;

public class TestClass {
        public String hallo;
        public String halloSecond;

        TestClass(String hello){
                hallo = hello;
                halloSecond = "Saluto!";
        }
        public static void main(String[] args) {
                TestClass test = new TestClass("Tjena!");
                System.out.println("I want "Tjena!": " + test.hallo);
                TestClass testSecond = new TestClass("1");
                System.out.println("I want Saluto!:" + test.halloSecond);
                System.out.println("I want Saluto!:" + testSecond.halloSecond);

                // How can I get glob.vars like the "Saluto!"?
        }
}


The important thing to note is that instance variable declarations go inside the class declaration, but outside of the constructor or any method. I always put them at the top.

import java.util.*;
import java.io.*;

public class TestClass {

        // Instance variables
        public String hallo;

        TestClass(String hello){
          hallo = hello;
        }

        public static void main(String[] args) {
                TestClass test = new TestClass("Tjena!");
                System.out.println("I want Tjena!:" + test.hallo);
                TestClass testSecond = new TestClass("Saluto");
                System.out.println("I want Saluto!:" + testSecond.hallo);
        }
}

Your example doesn't really suggest the use of "global" or class variables. Simply add the word static. Also, you then prefix the variable with the class name, not an instance name when referencing it:

import java.util.*;
import java.io.*;

public class TestClass {

        // Class variables
        public static String hallo;

        TestClass(String hello){
          hallo = hello;
        }

        public static void main(String[] args) {
                TestClass test = new TestClass("Tjena!");
                // Reference class variable with "TestClass", not "test"
                System.out.println("I want Tjena!:" + TestClass.hallo);
                TestClass testSecond = new TestClass("Saluto");
                System.out.println("I want Saluto!:" + TestClass.hallo);
        }
}

To use "constants". Simply add "final" to the declaration. This means the variables won't change once they're declared:

import java.util.*;
import java.io.*;

public class TestClass {

        // Class "constants"
        public static final String hallo = "hello";
        public static final String halloSecond = "Saluto!";

        TestClass(){
        }

        public static void main(String[] args) {
                TestClass test = new TestClass();
                // Reference class variable with "TestClass", not "test"
                System.out.println("I want Tjena!:" + TestClass.hallo);
                TestClass testSecond = new TestClass();
                System.out.println("I want Saluto!:" + TestClass.halloSecond);
        }
}


The problem in your "clarification" (which seems to be a completely separate question) is that hallo is an instance variable which you are trying to access from static method. Static content does not belong to any instance and it would be impossible to know which instance to access. To fix that particular peace of code, declare the variables static also.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜