Is it possible to load classes dynamically and use them as type?

3

I'm trying to make a code that loads classes dynamically and can use them to instantiate and be used to cast. I can create an instance in the newly loaded class using the minhaclasse.newInstance() method, but I can not use the newly loaded class as a type. For example: minhaClasse meuObj = new minhaClasse(); Does not work. Is it possible to do this?

Here is the code I was trying to do:

URL classUrl;
classUrl = new URL("file:///C:/classes/");
URL[] classUrls = { classUrl };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("Operation");
Class MyIn = ucl.loadClass("MyInter"); 
Object o = c.newInstance(); //ISSO FUNCIONA
System.out.println(((MyIn) o).sum(2, 4)); //ISSO NÃO FUNCIONA. Mensagem de erro: MyIn cannot be resolved to a type
    
asked by anonymous 01.04.2016 / 15:49

1 answer

2

Not possible.

Java is a language of strong types. This means that the compiler checks if the methods and attributes you are accessing exist and are compatible with code usage. The only way to do this is if the compiler has access to the classes being used and the code is importing those dependencies correctly.

If it were possible to use weak typing as in scripting languages the cast would have no advantage whatsoever, just call any method on the generic object and that's it.

Anyway, what you're trying to do is basically force Java to create a type dynamically without however presenting a definition of that type.

To access methods and attributes of dynamically loaded classes, you must use reflection. There are already some answers here, including mine that teaches you to do this, but basically you can use the getMethod method of the class and retrieve a reference to the method, then you use the invoke method to execute the method.

See an example from documentation :

public class InvokeMain {
    public static void main(String... args) {   
        try {    
            Class<?> c = Class.forName(args[0]);     
            Class[] argTypes = new Class[] { String[].class };   
            Method main = c.getDeclaredMethod("main", argTypes);     
            String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);    
            System.out.format("invoking %s.main()%n", c.getName());      
            main.invoke(null, (Object)mainArgs);
        } catch (ClassNotFoundException x) {     
            x.printStackTrace(); 
        } catch (NoSuchMethodException x) {      
            x.printStackTrace();    
        } catch (IllegalAccessException x) {     
            x.printStackTrace();    
        } catch (InvocationTargetException x) {      
            x.printStackTrace();    
        } 
    } 
}
    
02.04.2016 / 00:56