简体   繁体   English

实例化泛型类型

[英]Instantiate generic type

I'm trying to instantiate a new object by Class clazz like this: 我试图通过Class clazz实例化一个新对象,如下所示:

Code: 码:

public class EntityType {
    private Map json = null;
    public EntityType(Map json){
        this.json = json;
    }
    public <T> T getAs(Class<T> clazz){
        final Class<T> clz = clazz;
        T obj = null;
        try {
            if (checkMap(json)){
                obj = clz.newInstance();
            }
        } catch (Exception e){
            if (e instanceof InstantiationException){
                e.printStackTrace();
            } else if (e instanceof IllegalAccessException){
                e.printStackTrace();
            } else {
                e.printStackTrace();
            }
        }
        return obj;
    }
}

This is how I use the code: 这就是我使用代码的方式:

EntityType type = new EntityType(map); // map contains values 
User user = type.getAs(User.class);

java.lang.InstantiationException is thrown for the above code. 抛出上面代码的java.lang.InstantiationException

What could be wrong in my code? 我的代码可能有什么问题?

Update: 更新:

    @Entity(name = "user")
    public class User { 
        @Id 
        private String id;
        @Column
        private String name;
        @Column
        private Long age;
        public User() {}
       // Setters and getter 
   }

Full stack trace: 完整堆栈跟踪:

java.lang.InstantiationException: org.goo.AnnotationTest$User
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:325)
    at org.goodb.client.Goo$EntityType.getAs(Goo.java:90)
    at org.goo.AnnotationTest.doTest(AnnotationTest.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

您可能在用户的类中没有默认构造函数

The exception stack trace says 异常堆栈跟踪说

java.lang.InstantiationException: org.goo.AnnotationTest$User

which suggests that User is a nested or inner class rather than a top-level one. 这表明User是嵌套或内部类而不是顶级类。 Static nested classes behave like top-level ones but for non-static inner classes, every instance is associated with a particular instance of its containing class and the compiler adds an extra parameter to the front of the parameter list for every constructor to pass in the appropriate containing instance. 静态嵌套类的行为类似于顶级类,但对于非静态内部类,每个实例都与其包含类的特定实例相关联,并且编译器在参数列表的前面添加一个额外参数,以便每个构造函数都传入适当的包含实例。 What in the source code looks like 源代码中的内容是什么样的

public User() {}

actually corresponds in the bytecode to something like 实际上在字节码中对应的东西就像

public User(AnnotationTest containingInstance) { this.container = containingInstance; }

(not with those parameter/field names but you get the idea). (不是那些参数/字段名称,但你明白了)。 So your User class does not in fact have a no-argument constructor. 所以你的User类实际上没有无参构造函数。

If you declared the User class as a top-level class or marked it static then it would work as you expect it to. 如果您将User类声明为顶级类或将其标记为static那么它将按预期工作。

You have a generic method but you ain't passing it the type parameter. 您有一个通用方法,但您没有传递类型参数。 Try this: 尝试这个:

 User user = type.<User>getAs(User.class);

If you share more code with us I can help you more. 如果您与我们分享更多代码,我可以为您提供更多帮助。 For example I'd like to see the full stack trace and the User class. 例如,我想看到完整的堆栈跟踪和User类。

As per javadoc description : 根据javadoc描述:

 * @exception  InstantiationException
 *               if this {@code Class} represents an abstract class,
 *               an interface, an array class, a primitive type, or void;
 *               or if the class has no nullary constructor;
 *               or if the instantiation fails for some other reason.

I think you do not have "nullary constructor", or most likely said : default constructor. 我认为你没有“nullary constructor”,或者很可能说:默认构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM