3
class TestCase{

  static{

    System.out.println("hello");

    return;

  }
  public static void main(String[] args){

    System.out.println("main");

  }

}
ZhongYu
  • 19,446
  • 5
  • 33
  • 61

4 Answers4

3

A static block is meant to be used for initialization of static variables, there should be no need to call return or throw an Exception within one.

If you need to return or throw an Exception, then I suggest utilizing what the Java™ Tutorial for a Static Initialization Block says to do and assign a method instead:

class Whatever {
    public static varType myVar = initializeClassVariable();

    private static varType initializeClassVariable() {
        // initialization code goes here
    }
}

Taken from https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
  • @MoulaAliShaik You're welcome! If I've solved your problem, feel free to upvote/accept the answer by clicking the green tick on the left of the post. – Jacob G. Apr 20 '17 at 03:29
2

A return is not allowed because a static block is not strictly speaking a method. There is no "caller" to return to, and certainly nothing to return a value to. Besides, it is always possible to achieve the local flow control effect of a return-with-no-expression by restructuring the code a little bit.

(In your example, the return is redundant anyway ... from a local flow control perspective.)

In short, return is not allowed because it doesn't make sense. (Just like you can't use continue in code that isn't within a loop statement.)


Exceptions that propagate out of static blocks are problematic. Basically, there is no way for application code to catch and deal with them.

  • The whole point of the checked / unchecked distinction is to ensure that certain exceptions cannot be ignored. Therefore the Java language treats a static block propagating checked exception as a compilation error.

  • On the other hand, an unchecked exception is allowed to be thrown in a static block (and not caught). This leads to an ExceptionInInitializerError, and leaves the class that you were trying to initialize in a "dead" state. Typically the application cannot recover from this.

    Why allow this? Given the myriad ways that an unchecked exception can arise, it would be impractical for the Java language to insist that they are dealt with inside the static initializer block. Besides, an unexpected + unchecked exception is a really an application bug. The simplest / safest way to deal with a bug is for the application to die ... leaving evidence for a programmer to diagnose and fix the bug.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

This question also applies to instance initializers as well as static initializers.

The return statement could be allowed, and it would be as useful as return in a void method. However, I think the biggest problem is the ambiguity in presence of multiple initializers:

static{  // 1
    ...
    ...return;
    ...
}
static{  // 2
    ...
}

if return is executed, does it just terminate block 1, and continue to block 2, or does it terminate all static initilization code?

For the question of throw, see Why is it not allowed to throw an exception in a Java instance initialization block?

My understanding is that, if a static/instance initializer unconditionally throws an exception, the class/constructor will always fail, rendering it pretty much useless. Therefore Java forbids it.

Workarounds:

return can be simulated by break from a labeled block:

static
{
    STATIC:
    {
        break STATIC;
    }
}

Unconditional throw can be achieved by if(true)

static
{
    if(true) throw new Error();
}

(Java specifically pretends to not know that the statement is definitely executed)

Community
  • 1
  • 1
ZhongYu
  • 19,446
  • 5
  • 33
  • 61
0

Because they can't be declared to either return a value or throw an exception. They are essentially anonymous static void methods that don't throw checked exceptions.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    They can't throw any exception, including Errors or RuntimeExceptions. (All will result in a "Initializer does not complete normally" error). Which is a bit silly because you can call a method that throws an unchecked exception from a static inititializer, but that's just how it is. – Erwin Bolwidt Apr 20 '17 at 02:11
  • @ErwinBolwidt They *can* throw `RuntimeExceptions` or `Errors`, and the consequence of doing so is as you describe. They can't throw *checked* exceptions because the compiler won't let them. – user207421 Apr 20 '17 at 02:12
  • and if the `exception` was caught, then what is the state of the Object - constructed or not? – Scary Wombat Apr 20 '17 at 02:13
  • 1
    @EJP Try it : `static { throw new Error("y"); }` will result in an immediate compile error. – Erwin Bolwidt Apr 20 '17 at 02:13
  • @ScaryWombat No object has been constructed yet either partially or otherwise, because the *class* is being initialized. This is prior to calling any constructors. – user207421 Apr 20 '17 at 02:14
  • @ScaryWombat I think you've just created Quantum Java – Jacob G. Apr 20 '17 at 02:14
  • @ErwinBolwidt They can engage in behaviour which will result in those exceptions being thrown. – user207421 Apr 20 '17 at 02:15
  • 1
    @EJP Geez EJP, I'm trying to make a constructive comment so that you can improve your answer. Why do you need to always "win" a discussion? – Erwin Bolwidt Apr 20 '17 at 02:17
  • @ErwinBolwidt I wasn't aware that it was a contest. Don't make personal remarks here. – user207421 Apr 20 '17 at 02:19
  • Thank you very much for you explanation – Moula Ali Shaik Apr 20 '17 at 03:24
  • @ErwinBolwidt - they can throw unchecked exceptions - but they cannot do so unconditionally, i.e. all execution paths lead to an exception. – ZhongYu Apr 20 '17 at 04:16