Loading a Class from a String

前端 未结 9 2271
[愿得一人]
[愿得一人] 2020-12-13 09:15

I want to instantiate a class by the value of a String. I found several tutorials that show several methods for doing this. The class MUST inherit from a certain interface

相关标签:
9条回答
  • 2020-12-13 09:53

    Here's how I would do it:

    ImplementMe noCastNeeded = 
        this.getClassLoader()
            .loadClass("my.package.IImplementedYou")
            .asSubclass(ImplementMe.class).newInstance();
    

    There are some Exceptions to catch but that's ok I think. :)

    0 讨论(0)
  • 2020-12-13 09:53

    You will need a cast, because the compiler cannot tell from the code that the object is of type ImplementMe. It thus requires the programmer to issue a cast, which will throw a ClassCastException if the object is not an ImplementMe instance.

    0 讨论(0)
  • 2020-12-13 09:57

    No, there is no better way (by design). You are not supposed to do this, Java is designed as a type-safe language. However, I can understand that you sometimes need to do things like this, and for that purposes you can create a library function like this:

    public <T> T instantiate(final String className, final Class<T> type){
        try{
            return type.cast(Class.forName(className).newInstance());
        } catch(InstantiationException
              | IllegalAccessException
              | ClassNotFoundException e){
            throw new IllegalStateException(e);
        }
    }
    

    Now your client code can at least call this method without casting:

    MyInterface thingy =
        instantiate("com.foo.bar.MyInterfaceImpl", MyInterface.class);
    
    0 讨论(0)
  • 2020-12-13 09:58

    You can shorten it a bit like

    ImplementMe a = (ImplementMe) Class
                                   .forName("my.package.IImplementedYou")
                                   .newInstance();
    

    but you can't get rid of the cast. There may be a way to avoid the cast, but only if you can avoid the subproblem of loading class by name.

    0 讨论(0)
  • 2020-12-13 09:59

    Try Class.forName("my.package.IImplementedYou").

    0 讨论(0)
  • 2020-12-13 10:00
    (MyInterface)Class.forName(className).newInstance()
    
    0 讨论(0)
提交回复
热议问题