Java Reflection Constructor Example

0

We have seen how to create instantiate a class using Class.newInstance(). In this article, we will see how to use the Constructor object to instantiate the class.

Multiple implementations of a class

Language interface defines a language. Once we have instantiated a language class, we will know its name and the version. Since Language is an interface, we will provide the implementations in a properties file.

We also provide the version in the same file. If class name is com.javarticles.reflection.JavaLang, its version# would be in com.javarticles.reflection.JavaLang.ver.

factory.properties:

com.javarticles.reflection.Language=com.javarticles.reflection.JavaLang,com.javarticles.reflection.RubyLang
com.javarticles.reflection.JavaLang.ver=1.8

If the class name specified doesn’t implement Language then we must throw some exception like IllegalArgumentException.

Language:

package com.javarticles.reflection;

public interface Language {
    String getName();
    String getVersion();
}

JavaLang:

package com.javarticles.reflection;

public class JavaLang implements Language {
    private String ver;
    
    public JavaLang(String ver) {
        this.ver = ver;
    }
    
    public String getName() {
        return "Java";
    }

    public String getVersion() {
        return ver;
    }

    public String toString() {
        return JavaLang.class.getName() + ":" + getName() + ":" + ver;
    }
}

RubyLang:

package com.javarticles.reflection;

public class RubyLang implements Language {

    public String getName() {
        return "Ruby";
    }

    public String getVersion() {
        return "2.3.0";
    }

    public String toString() {
        return JavaLang.class.getName() + ":" + getName() + ":" + getVersion();
    }
}

Default Constructor

Calling Class.newInstance() is equivalent to create an object using the default constructor, the constructor with no arguments. If there is no language version, we will create object using the default constructor.

Using constructor objects to instantiate a class

We can also create instances using the constructor object java.lang.reflect.Constructor. The Class.getConstructor() method takes in the specific parameter types that the actual constructor of the target object accepts and returns us the public constructor object. The returned constructor object represents the actual constructor object and we can use it instantiate the class.

If there is no constructor declared for the parameter list specified, getConstructor() throws the NoSuchMethodException.

JavaReflectionConstructorInstanceExample:

package com.javarticles.reflection;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class JavaReflectionConstructorInstanceExample {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException, NoSuchMethodException, SecurityException,
            InstantiationException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        
        Map<Class<?>, Object> classMap = new HashMap<>();
        URL url = JavaReflectionConstructorInstanceExample.class
                .getResource("factory.properties");
        Properties prop = new Properties();
        prop.load(url.openStream());
        System.out.println("Properties: " + prop);
        String className = Language.class.getName();
        System.out.println("Implementation class names for " + className + " are "
                + prop.get(className));
        String[] implementations = ((String) prop.get(className)).split(",");
        
        for (String implClassName : implementations) {
            Class<?> implClass = loadClass(implClassName);
            if (!Language.class.isAssignableFrom(implClass)) {
                throw new IllegalArgumentException(implClass + " is not of type " + Language.class.getName());
            }
            String verKey = implClassName + ".ver";
            System.out.println(verKey + "=" + prop.get(verKey));
            String ver = (String) prop.get(verKey);
            Language lang;
            if (ver != null && !ver.trim().isEmpty()) {
                Constructor<?> constructor = implClass
                        .getConstructor(String.class);
                lang = (Language) constructor.newInstance(ver);                
            } else {
                Constructor<?> constructor = implClass
                        .getConstructor(new Class[]{});
                lang = (Language) constructor.newInstance();
            }
            classMap.put(implClass, lang);
        }
        
        System.out.println("Class->Implementations: \n" + classMap.values());
    }

    private static Class<?> loadClass(String className)
            throws ClassNotFoundException {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        // No thread context class loader -> use class loader of this class.
        if (cl == null) {
            cl = JavaReflectionConstructorInstanceExample.class
                    .getClassLoader();
        }

        // getClassLoader() returning null indicates the bootstrap ClassLoader
        if (cl == null) {
            cl = ClassLoader.getSystemClassLoader();
        }
        return cl.loadClass(className);
    }
}

Output:

Properties: {com.javarticles.reflection.Language=com.javarticles.reflection.JavaLang,com.javarticles.reflection.RubyLang, com.javarticles.reflection.JavaLang.ver=1.8}
Implementation class names for com.javarticles.reflection.Language are com.javarticles.reflection.JavaLang,com.javarticles.reflection.RubyLang
com.javarticles.reflection.JavaLang.ver=1.8
com.javarticles.reflection.RubyLang.ver=null
Class->Implementations: 
[com.javarticles.reflection.JavaLang:Java:1.8, com.javarticles.reflection.JavaLang:Ruby:2.3.0]

Download the source code

This was an example about creating instance using Java Reflection’s Constructor.

You can download the source code here: javaReflectionConstructorExample.zip
Share.

Comments are closed.