How to break out initialization block? - java

I have a class looks like this
class Some {
private enum Inner {
}
}
And I'm trying to find the Inner class in a initialization block of my test class.
class SomeTest {
private static final Class<?> INNER_CLASS;
{
for (final Class<?> declaredClass: Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
INNER_CLASS = declaredClass;
// Variable `INNER_CLASS` might be assigned in loop
// break? return?
}
}
throw new ExceptionInitializerError("failed to find Inner.class");
}
}
The compiler doesn't like this and I couldn't find any better way.
How can I solve this? Is there any good pattern for this?

static and instance initialization block cannot throw checked exceptions as there is no way to declare that those blocks throws these execeptions. Change ExceptionInitializerError to RuntimeException (or any subclass) and wrap your code in try-catch
Besides here, you are not returning nor breaking thus you always throw exception.
As for "breaking out" well simply yo dont. You have to write that block as it would be body of void method but with the restriction that you cannot use return anywhere.

There are a few problems with your code:
You have the exception name incorrect. The exception you are trying to throw is called ExceptionInInitializerError not ExceptionInitializerError. That is one reason why it won't compile.
Never1 throw Error or subclasses of Error.
If you need to throw an unchecked exception, throw RuntimeException. Or better still, pick something more specific or define and use your own custom (unchecked) exception class.
This should (probably) be a static initializer block, not a plain (instance) initializer. You want this code to be executed once ... not every time a SomeTest instance is created.
Bailing out of a static initializer block is something you want to avoid. It basically leaves you with a dead application ... because the enclosing class and any classes that depend on it become uninitializable.
Having said that, the following might be a more appropriate structure:
static {
BlahType tmp = null;
label: {
for (...) {
if (...) {
tmp = ...;
break label;
}
}
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
Note that we need to do the final assignment to FINAL_VAR in a way that ensures that it is definitely assigned. (My guess is that is a second reason you were getting compilation errors.)
And a more natural way to write the above would be:
static {
BlahType tmp = null;
for (...) {
if (...) {
tmp = ...;
break;
}
}
if (tmp == null) {
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
1 - Maybe a bit too strong. I would say that throwing AssertionError is OK ... assuming that you intend for it never be caught / recovered from. In this case, recovery is moot anyway.

Use intermediate variable before final assignment.
class SomeTest {
private static final Class<?> INNER_CLASS;
static {
Class<?> innerClass = null;
for (final Class<?> declaredClass: Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
innerClass = declaredClass;
}
}
if (innerClass == null) {
throw new ExceptionInitializerError("failed to find Inner.class");
}
INNER_CLASS = innerClass;
}
}

There are couple of issues:
The exception is always thrown
You are assigning to a final variable in a loop
The initialization block is not static and assigning to a static final variable
Check this out:
class SomeTest {
private static final Class<?> INNER_CLASS;
static {
Class<?> foundClass = null;
for (final Class<?> declaredClass : Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
foundClass = declaredClass;
// Variable `INNER_CLASS` might be assigned in loop
// break? return?
}
}
INNER_CLASS = foundClass;
// throw new Exception("failed to find Inner.class");
}
}

Related

How to catch exception which happens at initialization of Java class field?

If there is an exception which happens during the initialization of the class field, how would you catch it?
For instance:
class a{
int a = 1 / 0;
}
Here exception occurs at the field level.
I know that I could do:
class a {
a() {
try {
this.a = 1 / 0;
} catch (Throwable a) {}
}
int a;
}
But just out of curiosity, is it possible to do it while initializing the field?
Additional info: I am asking this because in my newest project I have one field which I want to initialize to the new instance of the object, and it would be cool to just write a = new Object(); but I can not since the constructor of that particular type throws the checked exception.
is it possible to do it while initializing the field?
You can define a method:
class a {
int a = aValue();
private int aValue() {
try
{
return 1/0;
}
catch (Throwable a){
// ...but now you need to return something, or (re)throw an exception.
}
}
}
or use an instance initializer:
class a {
int a;
{
try
{
this.a=1/0;
}
catch (Throwable a){
// You don't need to do anything here, unless `a` were `final`.
}
}
}
but note that instance initializers are inlined into the constructor (or, at least, any constructor that invokes super(...) explicitly or implicitly, rather than this(...)), so this is effectively the same as putting it in the constructor as in the question.
It's really hard to catch those. As a consequence, it is highly advisable to ensure that static initializers do not throw anything that one could feasibly want to catch. (e.g. throwing an OutOfMemoryError is fine, it's not likely someone would want to write code that catches this and does an alternative path or attempts to solve the problem).
This generally starts by replacing your static initializer with a method invocation. Replace:
static int a; static {a = 1/0; }
with:
static int a = calculateA();
private static int calculateA() {
return 1/0;
}
This is just a step along the path, of course. Move the initializing code (the calculateA method) to a separate class and now you can test it on its own, without even running into problem of catching exceptions thrown during static init of a class.
Once you've taken care of this, you can use this 'trick' to move the problem around. Imagine that the value of a is required for 2 of the methods in this class. Then, 'defer' the exception:
public class Example {
private static final int a;
private static final Throwable aProblem;
static {
int a = 0;
Throwable aProblem = null;
try {
a = calculateA();
} catch (RuntimeException e) {
aProblem = e;
}
Example.a = a;
Example.aProblem = aProblem;
}
private static int calculateA() { return 1/0; }
public static void apiMethodUsingA1() {
if (aProblem != null) throw aProblem;
return a;
}
public static void apiMethodUsingA2() {
if (aProblem != null) throw aProblem;
return a + 5;
}
}
If none of these options are available, for example because A is not written by you and cannot be changed, then you must delegate the A class as 'bad API / crappy library', and you do what you always do when you face such a library: Work around it, accept that you need to write hard to maintain / ugly code, and if it's really bad, write a wrapper to isolate the problems. Maybe even use reflection.
This is one guaranteed way to isolate the exception into a codeblock:
package com.foo;
class Example {
static int a = 1/0;
}
class Main {
public static void main(String[] args) throws Exception {
try {
Class<?> c = Class.forName("com.foo.Example");
} catch (ExceptionInInitializerError e) {
System.err.println("Hey I caught it");
Throwable actualException = e.getCause();
// do something with it here
actualException.printStackTrace(); // not this - this is for debugging only!
}
}
}

Is this the correct exercise solution?

There is a exercise from Thinking in Java:
Create a class called FailingConstructor with a constructor that might
fail partway through the construction process and throw an exception.
In main(), write code that properly guards against this failure.
This is my solution:
class E1 extends Exception {
private FailingConstructor f;
E1(FailingConstructor f) { this.f = f; }
FailingConstructor getF() { return f; }
}
class FailingConstructor {
private Integer value;
FailingConstructor(int i) throws E1 {
if (i < 0) throw new E1(this);
value = i;
}
void set(int value) { this.value = value; }
public String toString() { return value.toString(); }
}
public class Program {
public static void main(String[] args) {
try {
FailingConstructor f2 = new FailingConstructor(-11);
} catch (E1 e) {
e.getF().set(0);
System.out.println(e.getF());
}
}
}
Could you please tell me, is this the correct exercise solution? Solution I found (here) looks rather strange and illogicaly and I think my solution is better than this.
Passing a reference of the half constructed instance to the constructor of the exception seems like a bad idea to me.
And mutating that instance in the catch clause serves no purpose, since after the catch clause is executed, your code will have no reference to that instance anyway.
The catch clause should either report that an exception occurred (print an error message or stack trace), throw a different exception if applicable or - if properly guards against this failure means that the successful creation of an instance must be ensured - create a new instance of FailingConstructor whose creation is guaranteed not to throw an exception. If you choose the last approach, you should declare the FailingConstructor variable before the try block, in order for it to remain in scope after the try-catch block.
public class Program {
public static void main(String[] args) {
FailingConstructor f2 = null;
try {
f2 = new FailingConstructor(-11);
} catch (E1 e) {
f2 = new FailingConstructor(); // one way to recover from the exception
// is to use a different constructor
// that doesn't throw an exception
}
// now you can access f2
}
}
Leaking the reference to the partly-constructed instance via the throw new E1(this) is ill-advised.
It lets you call e.getF().set(-1), and use the instance afterwards - which is exactly what the exception is being thrown to guard against.
There is no problem with throwing an exception - the problem is the reference to FailingConstructor that it is constructed with. Remove this (and the getF() method etc), and it is fine.

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);
}}
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;
}
}
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..
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.

Catch exception while initializing static final variable

I have following code:
public class LoadProperty
{
public static final String property_file_location = System.getProperty("app.vmargs.propertyfile");
public static final String application-startup_mode = System.getProperty("app.vmargs.startupmode");
}
It reads from 'VM arguments' and assigns to variables.
Since static final variable is only initialized at class load,
how can I catch exception in case some one forgets to pass parameter.
As of now, when I am using 'property_file_location' variable, exception is encountered in following cases:
If value is present, and location is wrong, FileNotFound exception comes.
If it is not initialized properly(value is null), it throws NullPointerException.
I need to handle second case at time of initialization only.
Similiar is case of second variable.
Whole idea is
To initialize application configuration parameters.
If successfully initialized, continue.
If not, alert user and terminate application.
You can catch it this way:
public class LoadProperty
{
public static final String property_file_location;
static {
String myTempValue = MY_DEFAULT_VALUE;
try {
myTempValue = System.getProperty("app.vmargs.propertyfile");
} catch(Exception e) {
myTempValue = MY_DEFAULT_VALUE;
}
property_file_location = myTempValue;
}
}
You can use a static initializer block as suggested by the rest of the answers. Even better move this functionality to a static utility class so you can still use them as an one-liner. You could then even provide default values e.g.
// PropertyUtils is a new class that you implement
// DEFAULT_FILE_LOCATION could e.g. out.log in current folder
public static final String property_file_location = PropertyUtils.getProperty("app.vmargs.propertyfile", DEFAULT_FILE_LOCATION);
However if those properties are not expected to exist all the time, I would suggest to not initialize them as static variables but read them during normal execution.
// in the place where you will first need the file location
String fileLocation = PropertyUtils.getProperty("app.vmargs.propertyfile");
if (fileLocation == null) {
// handle the error here
}
You may want to use a static bloc :
public static final property_file_location;
static {
try {
property_file_location = System.getProperty("app.vmargs.propertyfile");
} catch (xxx){//...}
}

How to handle a static final field initializer that throws checked exception

I am facing a use case where I would like to declare a static finalfield with an initializer statement that is declared to throw a checked exception. Typically, it'd look like this:
public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");
The issue I have here is that the ObjectName constructor may throw various checked exceptions, which I don't care about (because I'd know my name is valid, and it's allright if it miserably crashes in case it's not). The java compiler won't let me just ignore this (as it's a checked exception), and I would prefer not to resort to:
public static final ObjectName OBJECT_NAME;
static {
try {
OBJECT_NAME = new ObjectName("foo:type=bar");
} catch (final Exception ex) {
throw new RuntimeException("Failed to create ObjectName instance in static block.", ex);
}
}
Because static blocks are really, really difficult to read. Does anyone have a suggestion on how to handle this case in a nice, clean way?
If you don't like static blocks (some people don't) then an alternative is to use a static method. IIRC, Josh Bloch recommended this (apparently not in Effective Java on quick inspection).
public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");
private static ObjectName createObjectName(final String name) {
try {
return new ObjectName(name);
} catch (final SomeException exc) {
throw new Error(exc);
}
}
Or:
public static final ObjectName OBJECT_NAME = createObjectName();
private static ObjectName createObjectName() {
try {
return new ObjectName("foo:type=bar");
} catch (final SomeException exc) {
throw new Error(exc);
}
}
(Edited: Corrected second example to return from method instead of assign the static.)
Your code is perfectly valid. I don't find it difficult to read. Other ways would only make it more worse. They're only difficult to read for starters, because most of them are not familiar with that. Just follow the standard conventions with regard to ordering of the elements in the code. E.g. do not put static initializers halfway or at the whole bottom of the code and also do not have multiple of them spreading over the class. Just put one at top, after static declarations.
static blocks aren't difficult to read. So I'd recommend that solution.
However, you can wrap your object in another object, for example
ObjectNameWrapper which shares an interface with your ObjectName, and whose constructor calls your ObjectName constructor, hiding all checked exceptions that occur. But again, I'd go for the static option.
You can use a method annotated with Lombok's #SneakyThrows
public static final ObjectName OBJECT_NAME = createObjectName();
#SneakyThrows(SomeException.class)
private static ObjectName createObjectName() {
return new ObjectName("foo:type=bar");
}
This annotation makes a checked exception behaves like an unchecked one.

Categories

Resources