Alexander  Tolkachev
Alexander Tolkachev

Reputation: 227

How to handle Exception from Singleton java?

I have a singleton class

public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());

public SingletonText() {}
public static CompositeText getInstance() {
    return text;
}}

And TextReader constructor that could throw FileNameEception

public TextReader(String filename) throws FileNameException{
    if(!filename.matches("[A-Za-z0-9]*\\.txt"))
        throw new FileNameException("Wrong file name!");

    file = new File(filename);
}

How can I rethrow it to main and catch it there? Main class

public class TextRunner {

public static void main(String[] args) {
    // write your code here
    SingletonText.getInstance().parse();

    System.out.println("Parsed text:\n");
    SingletonText.getInstance().print();

    System.out.println("\n\n(Var8)Task1:");
    SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
    System.out.println("\n\n(Var9)Task2:");
    SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
    System.out.println("\n\n(Var16)Task3:");
    String result = SubStringReplace.replace(SingletonText.getInstance()
            .searchSentence(".*IfElseDemo.*"), 3, "EPAM");
    System.out.println(result);
}}

Upvotes: 1

Views: 621

Answers (3)

hagrawal7777
hagrawal7777

Reputation: 14658

Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.

In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What @Alexander Pogrebnyak has said is also true.

Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:

  • you need to create a singleton object of your CompositeText class.
  • create a setter method will create an object TextReader class using the file name string passed.
  • that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.

P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.

Code:

public class SingletonText {    
    private static CompositeText text = null;

    static{
        try {
            text = new CompositeText(new TextReader("text/text.txt").readFile());
        } catch (FileNameException e) {
            // TODO: re-throw whatever you want
        }
    }
    public SingletonText() {}
    public static CompositeText getInstance() {
        return text;
    }
}

Upvotes: 1

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45576

You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.

As a cause it will have your FileNameException.

If you don't do anything, default exception handler will print the whole stack trace to standard error.

Upvotes: 0

chico
chico

Reputation: 71

try to lazy initialze the singleton. something like this:

public class SingletonText {
private static CompositeText text;

public SingletonText() {
}

public static CompositeText getInstance() {
    if (text ==null) {
        text = new CompositeText(new TextReader("text/text.txt").readFile());
    }
    return text;
}
}

Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki: https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java Enjoy..

Upvotes: 0

Related Questions