Check whether a String value is convertible to an instance of a Wrapper class given as Class object?

This is the follow up of my answer to this Stack Overflow question. The question goes like this:

Suppose we have a String and a Class<?> object like this:

String string = "true";
Class<?> clazz = Integer.class;

How do we find that the value in string is convertible to an instance of class given by Class<?> clazz or not?

Assumption here is that, we are dealing with wrapper classes. It wouldn’t be that easy(if only possible) to do this for any normal class. Now, considering the fact that, every wrapper class has a method – valueOf(String), that converts a string value to an instance of that wrapper class, we can use some reflection hack to get around with this.

Here’s the working code:

public class ReflectionTest {

    public static void main(String... args) throws InvocationTargetException, IllegalAccessException {

        String string = "24";
        Class<?> clazz = Integer.class;

        Method method = null;

        try {
            method = clazz.getMethod("valueOf", String.class);
        } catch (NoSuchMethodException | SecurityException e) {
            System.out.println(e.getMessage());
        }

        if (method != null) {
            try {
                Object obj = method.invoke(null, string);
                System.out.println("String value converted to " +
                                   clazz.getSimpleName() +
                                   " instance: " + obj);

            } catch (IllegalArgumentException ex) {
                System.out.println(ex.getMessage());
                System.out.println("Failure : " + string +
                                   " is not of type " +
                                   clazz.getSimpleName());
            }
        }
    }
}

Assuming that there is no SecurityManager to prevent you from running this code, it will print:

Output:
String value converted to Integer instance: 24

So, what is that code actually doing? We’ll understand it step by step in the following paragraph.

We already have the Class object for Integer.class class. If you look at the Integer class, or any other wrapper classes, they have a static method – valueOf(String), which creates that wrapper class instance from passed String, and throws NumberFormatException if the string cannot be converted to the wrapper class instance.

We then use Class#getMethod(String, Class<?>...) method to get a Method instance for valueOf method in the following part:

method = clazz.getMethod("valueOf", String.class);

After we have got the Method instance, we try to invoke the method using Method#invoke(Object, Object...) method, passing null as first argument (To invoke a static method, we pass null as first argument), and the given String as second argument. This is done in following part of the code:

Object obj = method.invoke(null, string);

If the method invocation is successful, and the string value can be converted to an Integer, the next statement in the try block is executed, and the success message is printed. Else, if any exception is thrown, the error message in the catch block is printed.

The above code will pass, as the string "24" is parseable to Integer instance. You can try out the code giving an invalid integer value in String, and see if exception is thrown or not.

Final Note: An important point to note here is that for Boolean wrapper, any value other than true will give you a Boolean.FALSE instance. Even the null argument will give false. The Boolean#valueOf(String) method doesn’t throw any exception.

Advertisements

What’s wrong with calling Overridable method in constructor?

This is the follow-up post of my answer on – this Stack Overflow question. Basically the question goes like this:

The application is doing this when creating an instance of the class B using a load class by name method.

  • Calls overridden load() in class B, from A class constructor ( B extends A)
  • Initializes variables (calls “private string testString = null” according to debugger), nulling them out

The major issue with the code in that post is, the non-final base class (A) constructor invokes a non-final method, which is overridden in the derived class (B). Due to this, the code will behave unexpectedly. I’ll explain the issue in detail in the following post. But first of all, you should understand (if you not already do) what happens behind the scene, when you create an object of a class. For that, I suggest you to go through my last post – Object creation process: Inheritance. If you already know about the process, you can proceed further.

When a method of a class is called, it expects that the instance on which it is called is completely initialized, so that it can work freely on the data (fields) of that class. Now,  as explained in my last post (that I linked), when you create an instance of a class, first of all, all it’s super class members are initialized, then at the end, it’s own constructor executes further to initialize it’s own member fields. So, when an overridden method is called from the base class constructor, it will invoke the overridden version in derived class, rather than the base class. But at that point, the members of the derived class has not been initialized yet for the current instance (as super class constructor is not finished yet). That can cause trouble if that method is using the instance fields. Let’s understand it with the help of an example:

Code Talks Better: –

abstract class Operation {

    public Operation() {
        divide();
    }
    abstract int divide();
}

class Division extends Operation {

    private int numerator = 0;
    private int denominator = 0;

    public Division(int numerator, int denominator) {
        super();
        this.numerator = numerator;
        this.denominator = denominator;
    }

    int divide() {
        return numerator / denominator;
    }
}

Now from the main method, we create an instance of Division class:

public static void main(String... args) {
    Operation division = new Division(4, 2);
}

When you run the code, you shouldn’t be surprised on seeing the output:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Division.divide(Main.java:75)
	at Operation.(Main.java:58)
	at Division.(Main.java:69)
	at Main.main(Main.java:84)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:491)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

So, what do you think have happened? Basically, when the “Operation” class constructor invoked the “divide()” method, it overridden method in “Division” class is called. At that point, since the “numerator” and “denominator” are not yet initialized by the “Division” class constructor, they will have their default value 0. And thus you got “/ by zero” exception, as “denominator” is 0.

So, the moral of the post is: –

  • Never invoke a non-final method of a non-final class inside it’s constructor. That method might have been overridden in one of it’s derived class, which might use the fields, which hasn’t been initialized yet.