-5

I am having a difficult time understanding the way static classes are using in the following scenario.

Let’s say I declare a class as follows:

public class TestLibrary {

    private static final TestLibrary library = new TestLibrary();
    private ErrorHandler errorHandler = null;

    public static TestLibrary getLibrary() {
        return library;
    }
    public ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    public int run(String[] args) {
        this.initialize(args);
    }

    private void initialize(String[] data) {
        library.errorHandler = new ErrorHandler();
    }   
}

I now change the class slightly to

private void initialize(String[] data) {
    errorHandler = new ErrorHandler();
}

I declare errorHandler in other classes as follows:

private ErrorHandler errorHandler = TestLibrary.getLibrary().getErrorHandler();

My code ultimately still functions the same when I use the instance of errorHandler in other classes, but I don’t understand why.

Question 1: Shouldn’t the 2nd case create a new ErrorHandler that is part of the object TestLibrary.errorHandler rather than library.errorHandler?

Question 2: Am I doing something wrong? Could you elaborate?

user432209
  • 20,007
  • 10
  • 56
  • 75
  • I get the feeling you want to make `TestLibrary` a singleton and don't know how to go about doing that. – azurefrog Dec 17 '15 at 16:15
  • With `library.errorHandler = new ErrorHandler()` you'll always be changing the object referenced by `library`'s `errorHandler`. With `errorHandler = new ErrorHandler();`, you'll be changing `this` object's `errorHandler`. – Sotirios Delimanolis Dec 17 '15 at 16:16
  • @jan Sotirios is correct. No imports in ErrorHandler. – user432209 Dec 17 '15 at 16:23
  • You are presenting a class which has a getter on a instance of the same class. Why not just use the constructor? – Romain Dec 17 '15 at 16:23
  • @Sotirios Delimanolis So, this confirms my suspicions. It is changing a different objects `ErrorHandler`. Thank you. – user432209 Dec 17 '15 at 16:26
  • The thing is, if you're only every using the `TestLibrary` instance referenced by the `static library` field, then it comes out to the same. You just have redundant references since `this == library` in that first example. – Sotirios Delimanolis Dec 17 '15 at 16:27

1 Answers1

0

What you have there is a static method getLibrary() that returns the same instance for all callers. That's called a Singleton - although there's better ways to code them.

Then again your supposed Singleton (TestLibrary) exhibits methods that when called change internal state - most important, the ErrorHandler.

This will cause strange behaviour, especially in multithreaded systems.

Code like this:

TestLibrary.getLibrary().run("".split(""));
ErrorHandler eh = TestLibrary.getErrorHandler();
assertEquals(eh, TestLibrary.getErrorHandler());

might fail. Because someone (meaning: some other thread) might have just happend to call init() between lines 2 and 3, causing ErrorHandler to be set to just another value.

If you need to initialize your TestLibrary before use, you should do it once, and once only - so you're better of putting this into the constructor of TestLibrary.

If you need TestLibraries that are intialized different throughout your code, you should remove the Singleton pattern and stick to plain

  TestLibrary tl = new TestLibrary();
  tl.run("".split(""));

Read more about Singleton in What is an efficient way to implement a singleton pattern in Java?

Community
  • 1
  • 1
Jan
  • 13,738
  • 3
  • 30
  • 55
  • The speculation is many threads will be using, but each instance of `TestLibrary` will be initialized with different parameters. Inside the "library" many objects refer back to the same instance of `errorHandler`. Thank you. – user432209 Dec 17 '15 at 16:37