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

Asked

Viewed 516 times

3

I’m trying to make a code that loads classes dynamically and can use them to create instances and be used for cast. I can create an instance in the newly loaded class using the method minhaclasse.newInstance() , but I cannot use the newly loaded class as a type. For example: minhaClasse meuObj = new minhaClasse(); It doesn’t work. It’s possible to do this?

Follow the code I was trying to make:

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
  • It would be possible to use MyIn.cast(o) but even then, you would not have the guarantee of which methods is composed the class of the object MyIn. Perhaps to execute this method, it would be possible to use reflection, if you know the names of the methods or have them in some xml, for example.

1 answer

2


Is not possible.

Java is a strong type language. This means that the compiler checks whether 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 correctly importing these dependencies.

If it was possible to use weak typing as in scripting languages the cast would have no advantage, just call any method in the generic object and ready.

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

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

See an example taken 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();    
        } 
    } 
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.