Java Reflection: Create an implementing class

JavaReflectionInterface

Java Problem Overview


Class someInterface = Class.fromName("some.package.SomeInterface");

How do I now create a new class that implements someInterface?

I need to create a new class, and pass it to a function that needs a SomeInterface as an argument.

Java Solutions


Solution 1 - Java

Easily, java.lang.reflect.Proxy to the rescue!

Full working example:

interface IRobot {

    String Name();

    String Name(String title);

    void Talk();

    void Talk(String stuff);

    void Talk(int stuff);

    void Talk(String stuff, int more_stuff);

    void Talk(int stuff, int more_stuff);

    void Talk(int stuff, String more_stuff);
}

public class ProxyTest {
    public static void main(String args[]) {
        IRobot robot = (IRobot) java.lang.reflect.Proxy.newProxyInstance(
                IRobot.class.getClassLoader(),
                new java.lang.Class[] { IRobot.class },
                new java.lang.reflect.InvocationHandler() {

            @Override
            public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
                String method_name = method.getName();
                Class<?>[] classes = method.getParameterTypes();

                if (method_name.equals("Name")) {
                    if (args == null) {
                        return "Mr IRobot";
                    } else {
                        return args[0] + " IRobot";
                    }
                } else if (method_name.equals("Talk")) {
                    switch (classes.length) {
                        case 0:
                            System.out.println("Hello");
                            break;
                        case 1:
                            if (classes[0] == int.class) {
                                System.out.println("Hi. Int: " + args[0]);
                            } else {
                                System.out.println("Hi. String: " + args[0]);
                            }
                            break;
                        case 2:
                            if (classes[0] == String.class) {
                                System.out.println("Hi. String: " + args[0] + ". Int: " + args[1]);
                            } else {
                                if (classes[1] == String.class) {
                                    System.out.println("Hi. int: " + args[0] + ". String: " + args[1]);
                                } else {
                                    System.out.println("Hi. int: " + args[0] + ". Int: " + args[1]);
                                }
                            }
                            break;
                    }
                }
                return null;
            }
        });

        System.out.println(robot.Name());
        System.out.println(robot.Name("Dr"));
        robot.Talk();
        robot.Talk("stuff");
        robot.Talk(100);
        robot.Talk("stuff", 200);
        robot.Talk(300, 400);
        robot.Talk(500, "stuff");
    }
}

Solution 2 - Java

Creating something which pretends to implement an interface on the fly actually isn't too hard. You can use java.lang.reflect.Proxy after implementing InvocationHandler to handle any method calls.

Of course, you could actually generate a real class with a library like BCEL.

If this is for test purposes, you should look at mocking frameworks like jMock and EasyMock.

Solution 3 - Java

If you want to go beyond interfaces, you might want to take a look at cglib and objenesis. Together, they will allow you to do some pretty powerful stuff, extending an abstract class and instantiating it. (jMock uses them for that purpose, for example.)

If you want to stick with interfaces, do what Jon Skeet said :).

Solution 4 - Java

Actually, you have to use the class name in Class.fromName() method and cast to your interface type. See if the sample below helps.

public class Main {
	
	public static void main(String[] args) throws Exception {
		Car ferrari = (Car) Class.forName("Mercedez").newInstance();
		System.out.println(ferrari.getName());
	}
}

interface Car {
	String getName();
}

class Mercedez implements Car {
	
	@Override
	public String getName() {
		return "Mercedez";
	}
	
}

class Ferrari implements Car {
	
	@Override
	public String getName() {
		return "Ferrari";
	}
	
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIsaac WallerView Question on Stackoverflow
Solution 1 - JavaPacerierView Answer on Stackoverflow
Solution 2 - JavaJon SkeetView Answer on Stackoverflow
Solution 3 - JavajqnoView Answer on Stackoverflow
Solution 4 - JavanandokakimotoView Answer on Stackoverflow