tmpConstructor empty in Java Class.newInstance() - java

I have tracked down an error to line 362 of the java.lang.Class class:
Constructor<T> tmpConstructor = cachedConstructor;
The variable does not seem to get assigned. In the debug expression windows it only says "tmpConstructor cannot be resolved to a variable". The cachedConstructor is not null.
An error is only thrown further down when a the newInstance() function is called:
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
Context:
Using JSON Plugin with the Struts2 framework to create Java objects from the received JSON.
The field it is trying to parse is a subclass of an abstract class.
On further inspection (thanks to user902838) I was missing that it can't instantiate an abstract class. So I need to find out how it can instantiate subclasses, which is a different question.
Can someone please explain to me why the tmpconstructor is empty?

It's hard to tell without any information about the class you're trying to instantiate or the exception/error you observe, but my best guess would be that the class does not have a nullary constructor. This program exhibits such a problem:
package example;
public class NewInstanceTest {
public NewInstanceTest(String s) {
}
public static void main(String[] args) throws Exception {
Class.forName("example.NewInstanceTest").newInstance();
}
}
The problem can be fixed by adding a nullary constructor:
package example;
public class NewInstanceTest {
/* nullary constructor: */
public NewInstanceTest() {
this("default");
}
public NewInstanceTest(String s) {
}
public static void main(String[] args) throws Exception {
Class.forName("example.NewInstanceTest").newInstance();
}
}
or by removing all non-nullary constructors so that Java will provide a nullary one automatically:
package example;
public class NewInstanceTest {
public static void main(String[] args) throws Exception {
Class.forName("example.NewInstanceTest").newInstance();
}
}

Related

class not found in java reflection

I'm learning java reflection. I am using the following code. But when I run, it gives the error
unreported exception ClassNotFoundException; must be caught or
declared to be thrown
Class className=Class.forName("First");
Maybe I'm going wrong somewhere. Please help me out. Here's the code:
import java.lang.reflect.Method;
public class First{
public void print(){}
public void ready(){}
}
public class test{
public static void main(String args[])
{
Class className=Class.forName("com.Test.First");
Method[] methods=className.getMethods();
System.out.println("First method is" + methods[0]);
}
}
All it's saying is that Class.forName throws this (non-runtime) Exception so you must handle it somehow. Here are two ways you could do it
public class test{
public static void main(String args[]) throws ClassNotFoundException
{
Class className=Class.forName("com.Test.First");
Method[] methods=className.getMethods();
System.out.println("First method is" + methods[0]);
}
}
Or
public class test{
public static void main(String args[])
{
try {
Class className=Class.forName("com.Test.First");
Method[] methods=className.getMethods();
System.out.println("First method is" + methods[0]);
}
catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
This line is the problem
Class className=Class.forName("com.Test.First");
in the Class.forName("com.Test.First"), you can replace com.Test.First with any gibberish and the compiler shouldn't care enough to validate it for you. All the compiler knows is that it is possible for there to not be a class com.Test.First and therefore you are responsible for handling a ClassNotFoundException.

Find out what exceptions a method throws programmatically

Imagine you have a method like:
public void doGreatThings() throws CantDoGreatThingsException, RuntimeException {...}
Is there any way to programmatically get the declared thrown exceptions by way of reflection?
// It might return something like Exception[] thrownExceptions = [CantDoGreatThingsException.class, RuntimeException.class]
You can use getExceptionTypes() method. You will not get Exception[] since such array would expect exception instances, but you will get instead Class<?>[] which will hold all thrown exception .class.
Demo:
class Demo{
private void test() throws IOException, FileAlreadyExistsException{}
public static void main(java.lang.String[] args) throws Exception {
Method declaredMethod = Demo.class.getDeclaredMethod("test");
Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
for (Class<?> exception: exceptionTypes){
System.out.println(exception);
}
}
}
Output:
class java.io.IOException
class java.nio.file.FileAlreadyExistsException
You can do that the reflection api.
// First resolve the method
Method method = MyClass.class.getMethod("doGreatThings");
// Retrieve the Exceptions from the method
System.out.println(Arrays.toString(method.getExceptionTypes()));
if the method requires parameters you need to supply them with the Class.getMethod() call.
Here's an example:
import java.io.IOException;
import java.util.Arrays;
public class Test {
public void test() throws RuntimeException, IOException {
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
System.out.println(Arrays.toString(Test.class.getDeclaredMethod("test").getExceptionTypes()));
}
}

Method having parameter "exception handling class objects" in java

Dear friends I am beginner to exception handling in java. I got this sample from one tutorial and I run this code its printed Arithmetic exception. If I remove that method which is have parameter as ArithmeticException then the first method called that is print Exception.
Please any one can explain what is happening with this code.
public class Question1 {
public static void javaHungry(Exception e) {
System.out.println("Exception");
}
public static void javaHungry(ArithmeticException ae) {
System.out.println("ArithmeticException");
}
public static void javaHungry(Object obj) {
System.out.println("Object");
}
/**
* #param args
*/
public static void main(String[] args) {
javaHungry(null);
}
}
When you overload methods and passed a parameter which suits for all, the most specific methods can be choose at run time.
The order of specificiation here is
ArithmeticException > Exception > Object
1) If you remove method with ArithmeticException it chooses Exception.
2) If you remove method with Exception it chooses Object.

Trying to throw own exception

I created my own throwable exception but when i want to throw it, the editor says, that a reference to an enclosing class required. I don't know, what i need to write.
Here's code:
public class Main {
int i = 0;
public Main() {
if (i == 0) throw new MyException("i must not be 0"); //Here it says about enclosing class
}
public static void main(String[] args) throws Exception {
new Main();
}
public class MyException extends Exception {
public MyException(String e) {
super(e);
}
}
}
Someone can tell me, where and what i must write?
You've defined MyException as an inner class of Main, then created an instance of it with no corresponding instance of Main available (since the main method is a static method).
You need to declare the exception class separately, outside of Main. Changing the access from public to package-private would let you keep the declaration in the same file. Otherwise, since you can have only one public class per file, it would need to go in its own file.
Alternatively you can define this as a static inner class, like so:
public class Main {
int i = 0;
public static void main(String[] args) throws Exception {
if (i == 0) throw new MyException("i must not be 0"); //Here it says about enclosing class
}
static class MyException extends Exception {
public MyException(String e) {
super(e);
}
}
}
Making the class static means it does not refer to an instance of the enclosing class.
Either declare MyException class as static
public static class MyException extends Exception {
public MyException(String e) {
super(e);
}
}
Or declare it in its own compilable .java file.
The way you have it now, MyException is an inner class of Main which requires an instance of Main to be initialized.
throw new Main().new MyException("i must not be 0");
After your edit, obviously everything works...
This is a general problem: Your class MyException is a nested class to your Main class, and it will always hold a reference to its enclosing instance. You want to make that exception class static, too.
Alternatively, in general but probably not in this case, you can instantiate the inner class using an instance of the outer class:
Main m = new Main();
throw m.new MyException();
Yes, that’s a new after the dot.

Java - using newInstance() on a Generic Class with Class<? extends myClass>: InstantiationException

I'm experiment with Generic Classes, and I've run into a hurdle which I cannot overcome. In short, I'm encountering an error which I do not understand why it is being thrown: InstantiationException
In the documentation it defines this exception as:
Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.
Now the problem that has me scratching my head is that I do not use the abstract or interface keyword. I've also heard that it could be due to not having a default constructor (which I have). Just to be sure, I reduced my code to the minimal possible, but still gives an error:
package Sandbox;
public class Sandbox {
public static void main(String[] args) {
Sandbox box = new Sandbox();
}
public Sandbox() {
aMethod(subThread.class);
}
public void aMethod(Class<? extends superThread> type) {
try {
System.out.println("isInterface: "+type.isInterface());
System.out.println("isAssignableFrom of subThread: "+type.isAssignableFrom(subThread.class));
superThread t = type.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
private class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
}
The Output:
isInterface: false
isAssignableFrom of subThread: true
java.lang.InstantiationException: Sandbox.Sandbox$subThread
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at Sandbox.Sandbox.aMethod(Sandbox.java:20)
at Sandbox.Sandbox.<init>(Sandbox.java:11)
at Sandbox.Sandbox.main(Sandbox.java:7)
I'm sure it's quite simple, but I cannot figure this one out. I've tried several things, but nothing has helped. Any and all help is appreciated.
Thanks,
Jon
It's because your inner classes are private. Simple fix:
public static class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
public static class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
The reasoning is because Class.newInstance must be able to access the constructor for the class you want to create.
Since the class is private, it's not accessible. Also, in order to access a non-static inner class, you essentially have to have an existing instance of the outer class (Sandbox), which newInstance doesn't have. As a result, having either public non-static or private static wouldn't work.
After zjagannatha pointed to the real problem, I also found a fix to my own code that allows me to keep the methods as non-static... essentially I discovered that even though the constructor had zero parameters, Constructor treated it as if it had one. I got it to list the parameter and found it odd that it needed a Sandbox class (I assume the one I'm currently working in) To allow a non-static class, I would need to change my newInstance code to this:
type.getConstructor(this.getClass()).newInstance(this);
and this works as well

Categories