Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Can final variables be initialized in static initialization block?

Tags:

java

static

final

Based on my understanding of the Java language, static variables can be initialized in static initialization block.

However, when I try to implement this in practice (static variables that are final too), I get the error shown in the screenshot below:

https://i.stack.imgur.com/5I0am.jpg

like image 545
Yatendra Avatar asked Feb 26 '10 06:02

Yatendra


People also ask

Can we initialize variable in static block Java?

Instance variables are initialized using initialization blocks. However, the static initialization blocks can only initialize the static instance variables. These blocks are only executed once when the class is loaded.

Can final variables be initialized?

A final variable can only be initialized once, either via an initializer or an assignment statement. There are three ways to initialize a final variable: You can initialize a final variable when it is declared. This approach is the most common.

How do you initialize a static final variable?

The only way to initialize static final variables other than the declaration statement is Static block. A static block is a block of code with a static keyword. In general, these are used to initialize the static members. JVM executes static blocks before the main method at the time of class loading.

Can constructor initialize static final variable?

If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.


3 Answers

Yes of course: static final variables can be initialized in a static block but.... you have implicit GOTOs in that example (try/catch is essentially a 'GOTO catch if something bad happens').

If an exception is thrown your final variables will not be initialized.

Note that the use of static constructs goes against Object-Oriented dogma. It may complicate your testing and make debugging more difficult.

like image 111
SyntaxT3rr0r Avatar answered Sep 18 '22 19:09

SyntaxT3rr0r


You can do this but you need to exit the static block by throwing an exception - you can rethrow the exception that was caught or a new one. Generally this exception must be a RuntimeException. You really should not catch a generic Exception but more specific exception(s) that might be thrown from within your try block. Finally, if a static initializer throws an exception then it will render the class unusable during that specific run because the JVM will only attempt to initialize your class once. Subsequent attempts to use this class will result in another exception, such as NoClassDefFoundError.

So, to work, your initializer should read something like this:

static {     try {         ...     } catch (Exception e) {         e.PrintStackTrace();         throw new InitializationFailedException("Could not init class.", e);     } } 

Assuming that InitializationFailedException is a custom RuntimeException, but you could use an existing one.

like image 28
Kevin Brock Avatar answered Sep 19 '22 19:09

Kevin Brock


public class MyClass
{
    private static final SomeClass myVar;

    static
    {
        Object obj = null;  // You could use SomeClass, but I like Object so you can reuse it
        try
        {
            obj = new SomeClass(...);    
        }
        catch(WhateverException err)
        {
            // Possibly nested try-catches here if the first exception is recoverable...
            // Print an error, log the error, do something with the error
            throw new ExceptionInInitializerError(err); 
        }
        finally
        {
            myVar = (SomeClass) obj;
        }
    }
}

Assuming no where upstream is in a position to catch either an ExceptionInInitializationError or a general Exception then the program should not ever try to use myVar. If however those are caught and the program doesn't end, then you need to code to watch for and handle myVar being null (or be happy with NullPointerExceptions coming out all over).

I'm not sure there is a good way to handle this.

like image 35
Matt Vang Avatar answered Sep 22 '22 19:09

Matt Vang