What does <init> signify in a Java exception?
For example:
BlahBlahException...
at java.io.FileInputStream.<init>(FileInputStream.java:20)
That the exception is thrown in the construction of the object, there are two options:
in the constructor
while initializing variables
Check out this demo I wrote: http://ideone.com/Mm5w5
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
try
{ new Test(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test2(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test3(); } catch (Exception e) { e.printStackTrace(); }
}
static class Test
{
Object obj = getObject();
Object getObject()
{ throw new RuntimeException("getObject"); }
}
static class Test2
{
Test2()
{
throw new RuntimeException("constructor");
}
}
static class Test3
{
Object obj1 = null;
String str = obj1.toString();
}
}
Produces:
java.lang.RuntimeException: getObject
at Main$Test.getObject(Main.java:24)
at Main$Test.<init>(Main.java:22)
at Main.main(Main.java:9)
java.lang.RuntimeException: constructor
at Main$Test2.<init>(Main.java:31)
at Main.main(Main.java:12)
java.lang.NullPointerException
at Main$Test3.<init>(Main.java:38)
at Main.main(Main.java:15)
<init>
is called
Instance Initialization method
which is created by your java compiler from the constructor you have defined. Though it is not valid method definition, your JVM expects this and anything that you put in the constructor will be executed in method. So when you an exception with from , you can be sure that it is from the constructor of the executed java class. Read more about this on Bill venner's design technique articles on Object Initialization.
Related
The question is about the result of the below code. The answer is compilation error. However I really do not understand why we can't have constructor in try/catch block. I will put the the code below:
public class Test {
try {
public Test() {
System.out.println("GeeksforGeeks");
throw new Exception();
}
}
catch(Exception e) {
System.out.println("GFG");
}
public static void main(String [] args) {
Test test= new Test();
}
}
Because the assignments are statements and statements are allowed only inside blocks of code(methods, constructors, static initializers, etc.)
here's the clean code
public class Test {
public Test()throws Exception {
System.out.println("GeeksforGeeks");
throw new Exception();
}
public static void main(String [] args) {
try {
Test test= new Test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because a constructor is a declaration, not a statement.
Your constructor can be called by other code, but merely declaring it does not execute it; that’s what new Test() does. Nothing is executed merely by declaring the constructor, so there is nothing that can throw an exception. Thus, there is nothing to catch.
In more general syntax terms, statements which don’t evaluate to a value can only exist in constructors, methods, and initialization blocks.
You can, however, do this:
public static void main(String[] args) {
try {
Test test = new Test();
} catch (Exception e) {
System.out.println(e);
}
}
new Test() actually executes the constructor, which is why it may throw an exception and thus you can legally attempt to catch any exception it may throw. Syntactically, all of the above code is inside a method (the main method), which is allowed.
I have the simple code below :
class Test {
public static void main(String[] args) {
Test t = new Test();
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
try {
t.throwAnotherException();
} catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
}
public void throwAnotherException() throws AnotherException {
throw new AnotherException();
}
public void handleException(Exception e) {
System.out.println("Handle Exception");
}
public void handleException(AnotherException e) {
System.out.println("Handle Another Exception");
}
}
class AnotherException extends Exception {
}
Why the method called in the second catch is the one with the signature void handleException(Exception e) whereas the kind of exception is AnotherException?
Overloaded methods are resolved at compile time, based on formal parameter types, not runtime types.
That means that if B extends A, and you have
void thing(A x);
void thing(B x);
then
B b = new B();
thing(b);
will look for a thing() that takes a B, because the formal type of b is B; but
A b = new B();
thing(b);
will look for a thing() that takes an A, because the formal type of b is A, even though its runtime actual type will be B.
In your code, the formal type of e is AnotherException in the first case, but Exception in the second case. The runtime type is AnotherException in each case.
AnotherException extends Exception, which means that anywhere you use "Exception", using an instance of "AnotherException" will qualify.
You should probably read up on Extending Classes for a more detailed explanation of how this works as it's very important in programming.
I guess you wanted to test which Exception is gonna get caught, right?
Then modify your code to throw just one Exception:
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
which is working as expected.
Exception is the super class so if you write your catch clause with (Exception e) first it will always gets satisfy and get executed.
to improve your code you can modify your code as written below.
class Test {
public static void main(String[] args) {
Test t = new Test();
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
try {
t.throwAnotherException();
}catch (AnotherException e) {
t.handleException(e);
}catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
}
public void throwAnotherException() throws AnotherException {
throw new AnotherException();
}
public void handleException(Exception e) {
System.out.println("Handle Exception");
}
public void handleException(AnotherException e) {
System.out.println("Handle Another Exception");
}
}
class AnotherException extends Exception {
}
The below statement is from thinking in java, "A derived-class constructor cannot catch exceptions thrown by its base-class constructor." But I am able to catch it. Can Anyone explain where I went wrong?
class Base {
Base() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
class Derived extends Base {
Derived() throws CloneNotSupportedException, RuntimeException {}
public static void main(String[] args) {
try {
Derived d = new Derived();
}
catch(CloneNotSupportedException e) {
e.printStackTrace();
}
catch(RuntimeException re){}
}
}
output:
java.lang.CloneNotSupportedException
at Base.<init>(Coffee.java:4)
at Derived.<init>(Coffee.java:9)
at Derived.main(Coffee.java:14)
You are not catching anything in the derived class's constructor. You catch the exceptions in the main method. Therefore you are not contradicting the quote you posted.
Here's how your derived-class constructor would have to look in order to catch an exception from the base-class constructor:
Derived() {
try {
super();
} catch (CloneNotSupportedException e) {
System.out.println("We have indeed caught an exception from the "+
"base-class constructor! The book was wrong!");
}
}
Try it and see what comes out.
I am using Javassist to write a HelloWorld class with main method. When I compile , I get an error as below. I am not sure what's wrong with String[] args in the main method ?
javassist.CannotCompileException: [source error] syntax error near "ng[] args)"
at javassist.CtNewMethod.make(CtNewMethod.java:78)
at javassist.CtNewMethod.make(CtNewMethod.java:44)
This is my code
public void createClass() {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("HelloClass");
try {
CtMethod m = CtNewMethod.make("public void sayHello() { System.out.println(\"Hello World\");}",ct);
ct.addMethod(m);
String str="public static void main(String[] args)";
CtMethod n = CtNewMethod.make(str,ct);
n.setBody("HelloClass a = new HelloClass();a.sayHello();");
ct.addMethod(n);
ct.writeFile();
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static void main(String[] args) {
JavaAssistExample inject = new JavaAssistExample();
inject.createClass();
}
As the javadoc for CtNewMethod states
The source code must include not only the method body but the whole declaration
It must therefore contain the {}, like
String str = "public static void main(String[] args){}";
However, two more things will give you problems.
First, you don't have a default (or a no arg) constructor. Add one
ct.addConstructor(CtNewConstructor.defaultConstructor(ct));
Second, the CtMethod#setBody(..) method completely replaces the method body. So you can't do what you are doing. If you want all of those calls, you'll need to put them together
n.setBody("{HelloClass a = new HelloClass();a.sayHello();}");
What does <init> signify in a Java exception?
For example:
BlahBlahException...
at java.io.FileInputStream.<init>(FileInputStream.java:20)
That the exception is thrown in the construction of the object, there are two options:
in the constructor
while initializing variables
Check out this demo I wrote: http://ideone.com/Mm5w5
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
try
{ new Test(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test2(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test3(); } catch (Exception e) { e.printStackTrace(); }
}
static class Test
{
Object obj = getObject();
Object getObject()
{ throw new RuntimeException("getObject"); }
}
static class Test2
{
Test2()
{
throw new RuntimeException("constructor");
}
}
static class Test3
{
Object obj1 = null;
String str = obj1.toString();
}
}
Produces:
java.lang.RuntimeException: getObject
at Main$Test.getObject(Main.java:24)
at Main$Test.<init>(Main.java:22)
at Main.main(Main.java:9)
java.lang.RuntimeException: constructor
at Main$Test2.<init>(Main.java:31)
at Main.main(Main.java:12)
java.lang.NullPointerException
at Main$Test3.<init>(Main.java:38)
at Main.main(Main.java:15)
<init>
is called
Instance Initialization method
which is created by your java compiler from the constructor you have defined. Though it is not valid method definition, your JVM expects this and anything that you put in the constructor will be executed in method. So when you an exception with from , you can be sure that it is from the constructor of the executed java class. Read more about this on Bill venner's design technique articles on Object Initialization.