简体   繁体   English

在 Java 中创建泛型实例?

[英]Create instance of generic type in Java?

Is it possible to create an instance of a generic type in Java?是否可以在 Java 中创建泛型实例? I'm thinking based on what I've seen that the answer is no ( due to type erasure ), but I'd be interested if anyone can see something I'm missing:根据我所看到的,我在想答案是no的(由于类型擦除),但如果有人能看到我遗漏的东西,我会很感兴趣:

class SomeContainer<E>
{
    E createContents()
    {
        return what???
    }
}

EDIT: It turns out that Super Type Tokens could be used to resolve my issue, but it requires a lot of reflection-based code, as some of the answers below have indicated.编辑:原来Super Type Tokens可以用来解决我的问题,但它需要大量基于反射的代码,正如下面的一些答案所表明的那样。

I'll leave this open for a little while to see if anyone comes up with anything dramatically different than Ian Robertson's Artima Article .我会把它打开一会儿,看看是否有人想出与 Ian Robertson 的Artima 文章截然不同的东西。

You are correct.你是对的。 You can't do new E() .你不能做new E() But you can change it to但是你可以把它改成

private static class SomeContainer<E> {
    E createContents(Class<E> clazz) {
        return clazz.newInstance();
    }
}

It's a pain.这是一种痛苦。 But it works.但它有效。 Wrapping it in the factory pattern makes it a little more tolerable.将它包装在工厂模式中使其更容易忍受。

I don't know if this helps, but when you subclass (including anonymously) a generic type, the type information is available via reflection.我不知道这是否有帮助,但是当您子类化(包括匿名)泛型类型时,类型信息可通过反射获得。 eg,例如,

public abstract class Foo<E> {

  public E instance;  

  public Foo() throws Exception {
    instance = ((Class)((ParameterizedType)this.getClass().
       getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
    ...
  }

}

So, when you subclass Foo, you get an instance of Bar eg,所以,当你继承 Foo 时,你会得到一个 Bar 的实例,例如,

// notice that this in anonymous subclass of Foo
assert( new Foo<Bar>() {}.instance instanceof Bar );

But it's a lot of work, and only works for subclasses.但这需要大量工作,并且仅适用于子类。 Can be handy though.不过可以很方便。

In Java 8 you can use the Supplier functional interface to achieve this pretty easily:在 Java 8 中,您可以使用Supplier功能接口轻松实现这一点:

class SomeContainer<E> {
  private Supplier<E> supplier;

  SomeContainer(Supplier<E> supplier) {
    this.supplier = supplier;
  }

  E createContents() {
    return supplier.get();
  }
}

You would construct this class like this:你会像这样构造这个类:

SomeContainer<String> stringContainer = new SomeContainer<>(String::new);

The syntax String::new on that line is a constructor reference .该行的语法String::new是一个构造函数引用

If your constructor takes arguments you can use a lambda expression instead:如果您的构造函数接受参数,您可以改用 lambda 表达式:

SomeContainer<BigInteger> bigIntegerContainer
    = new SomeContainer<>(() -> new BigInteger(1));

You'll need some kind of abstract factory of one sort or another to pass the buck to:你需要某种抽象工厂来推卸责任:

interface Factory<E> {
    E create();
}

class SomeContainer<E> {
    private final Factory<E> factory;
    SomeContainer(Factory<E> factory) {
        this.factory = factory;
    }
    E createContents() {
        return factory.create();
    }
}
package org.foo.com;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Basically the same answer as noah's.
 */
public class Home<E>
{

    @SuppressWarnings ("unchecked")
    public Class<E> getTypeParameterClass()
    {
        Type type = getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        return (Class<E>) paramType.getActualTypeArguments()[0];
    }

    private static class StringHome extends Home<String>
    {
    }

    private static class StringBuilderHome extends Home<StringBuilder>
    {
    }

    private static class StringBufferHome extends Home<StringBuffer>
    {
    }   

    /**
     * This prints "String", "StringBuilder" and "StringBuffer"
     */
    public static void main(String[] args) throws InstantiationException, IllegalAccessException
    {
        Object object0 = new StringHome().getTypeParameterClass().newInstance();
        Object object1 = new StringBuilderHome().getTypeParameterClass().newInstance();
        Object object2 = new StringBufferHome().getTypeParameterClass().newInstance();
        System.out.println(object0.getClass().getSimpleName());
        System.out.println(object1.getClass().getSimpleName());
        System.out.println(object2.getClass().getSimpleName());
    }

}

If you need a new instance of a type argument inside a generic class then make your constructors demand its class...如果你需要一个泛型类中类型参数的新实例,那么让你的构造函数要求它的类......

public final class Foo<T> {

    private Class<T> typeArgumentClass;

    public Foo(Class<T> typeArgumentClass) {

        this.typeArgumentClass = typeArgumentClass;
    }

    public void doSomethingThatRequiresNewT() throws Exception {

        T myNewT = typeArgumentClass.newInstance();
        ...
    }
}

Usage:用法:

Foo<Bar> barFoo = new Foo<Bar>(Bar.class);
Foo<Etc> etcFoo = new Foo<Etc>(Etc.class);

Pros:优点:

  • Much simpler (and less problematic) than Robertson's Super Type Token (STT) approach.比 Robertson 的 Super Type Token (STT) 方法简单得多(问题也更少)。
  • Much more efficient than the STT approach (which will eat your cellphone for breakfast).比 STT 方法(早餐会吃掉你的手机)效率更高。

Cons:缺点:

  • Can't pass Class to a default constructor (which is why Foo is final).不能将 Class 传递给默认构造函数(这就是为什么 Foo 是最终的)。 If you really do need a default constructor you can always add a setter method but then you must remember to give her a call later.如果你真的需要一个默认的构造函数,你总是可以添加一个 setter 方法,但你必须记住稍后给她打电话。
  • Robertson's objection... More Bars than a black sheep (although specifying the type argument class one more time won't exactly kill you).罗伯逊的反对意见......比害群之马更多的酒吧(尽管再次指定类型参数类不会完全杀死你)。 And contrary to Robertson's claims this does not violate the DRY principal anyway because the compiler will ensure type correctness.与 Robertson 的说法相反,这无论如何都不会违反 DRY 原则,因为编译器将确保类型正确性。
  • Not entirely Foo<L> proof.不完全是Foo<L>证明。 For starters... newInstance() will throw a wobbler if the type argument class does not have a default constructor.对于初学者......如果类型参数类没有默认构造函数, newInstance()将抛出一个 wobbler 。 This does apply to all known solutions though anyway.无论如何,这确实适用于所有已知的解决方案。
  • Lacks the total encapsulation of the STT approach.缺乏对 STT 方法的完全封装。 Not a big deal though (considering the outrageous performance overhead of STT).不过这没什么大不了的(考虑到 STT 惊人的性能开销)。

You can do this now and it doesn't require a bunch of reflection code.您现在可以执行此操作,并且不需要一堆反射代码。

import com.google.common.reflect.TypeToken;

public class Q26289147
{
    public static void main(final String[] args) throws IllegalAccessException, InstantiationException
    {
        final StrawManParameterizedClass<String> smpc = new StrawManParameterizedClass<String>() {};
        final String string = (String) smpc.type.getRawType().newInstance();
        System.out.format("string = \"%s\"",string);
    }

    static abstract class StrawManParameterizedClass<T>
    {
        final TypeToken<T> type = new TypeToken<T>(getClass()) {};
    }
}

Of course if you need to call the constructor that will require some reflection, but that is very well documented, this trick isn't!当然,如果您需要调用需要一些反射的构造函数,但有很好的文档记录,这个技巧不是!

Here is the JavaDoc for TypeToken .这是TypeTokenJavaDoc

Think about a more functional approach: instead of creating some E out of nothing (which is clearly a code smell), pass a function that knows how to create one, ie考虑一种更实用的方法:与其从无到有创建一些 E(这显然是一种代码异味),不如传递一个知道如何创建 E 的函数,即

E createContents(Callable<E> makeone) {
     return makeone.call(); // most simple case clearly not that useful
}

From Java Tutorial - Restrictions on Generics :来自Java 教程 - 对泛型的限制

Cannot Create Instances of Type Parameters 无法创建类型参数的实例

You cannot create an instance of a type parameter.您不能创建类型参数的实例。 For example, the following code causes a compile-time error:例如,以下代码会导致编译时错误:

public static <E> void append(List<E> list) {
    E elem = new E();  // compile-time error
    list.add(elem);
}

As a workaround, you can create an object of a type parameter through reflection:作为解决方法,您可以通过反射创建类型参数的对象:

public static <E> void append(List<E> list, Class<E> cls) throws Exception {
    E elem = cls.getDeclaredConstructor().newInstance();   // OK
    list.add(elem);
}

You can invoke the append method as follows:您可以按如下方式调用 append 方法:

List<String> ls = new ArrayList<>();
append(ls, String.class);

When you are working with E at compile time you don't really care the actual generic type "E" (either you use reflection or work with base class of generic type) so let the subclass provide instance of E.当您在编译时使用 E 时,您并不真正关心实际的泛型类型“E”(您使用反射或使用泛型类型的基类),因此让子类提供 E 的实例。

abstract class SomeContainer<E>
{
    abstract protected E createContents();
    public void doWork(){
        E obj = createContents();
        // Do the work with E 
     }
}

class BlackContainer extends SomeContainer<Black>{
    protected Black createContents() {
        return new Black();
    }
}

Here is an option I came up with, it may help:这是我想出的一个选项,它可能会有所帮助:

public static class Container<E> {
    private Class<E> clazz;

    public Container(Class<E> clazz) {
        this.clazz = clazz;
    }

    public E createContents() throws Exception {
        return clazz.newInstance();
    }
}

EDIT: Alternatively you can use this constructor (but it requires an instance of E):编辑:或者你可以使用这个构造函数(但它需要一个 E 的实例):

@SuppressWarnings("unchecked")
public Container(E instance) {
    this.clazz = (Class<E>) instance.getClass();
}

If you want not to type class name twice during instantiation like in:如果您不想在实例化过程中两次键入类名,例如:

new SomeContainer<SomeType>(SomeType.class);

You can use factory method:您可以使用工厂方法:

<E> SomeContainer<E> createContainer(Class<E> class); 

Like in:像:

public class Container<E> {

    public static <E> Container<E> create(Class<E> c) {
        return new Container<E>(c);
    }

    Class<E> c;

    public Container(Class<E> c) {
        super();
        this.c = c;
    }

    public E createInstance()
            throws InstantiationException,
            IllegalAccessException {
        return c.newInstance();
    }

}

Java unfortunatly does not allow what you want to do.不幸的是,Java 不允许您执行任何操作。 See the official workaround :请参阅官方解决方法

You cannot create an instance of a type parameter.您不能创建类型参数的实例。 For example, the following code causes a compile-time error:例如,以下代码会导致编译时错误:

public static <E> void append(List<E> list) {
    E elem = new E();  // compile-time error
    list.add(elem);
}

As a workaround, you can create an object of a type parameter through reflection:作为解决方法,您可以通过反射创建类型参数的对象:

public static <E> void append(List<E> list, Class<E> cls) throws Exception {
    E elem = cls.newInstance();   // OK
    list.add(elem);
}

You can invoke the append method as follows:您可以按如下方式调用 append 方法:

List<String> ls = new ArrayList<>();
append(ls, String.class);

You can use:您可以使用:

Class.forName(String).getConstructor(arguments types).newInstance(arguments)

But you need to supply the exact class name, including packages, eg.但是您需要提供确切的类名,包括包,例如。 java.io.FileInputStream . java.io.FileInputStream I used this to create a math expressions parser.我用它来创建一个数学表达式解析器。

Hope this's not too late to help!!!希望这不是太晚的帮助!!!

Java is type-safe, meaning that only Objects are able to create instances. Java 是类型安全的,这意味着只有对象才能创建实例。

In my case I cannot pass parameters to the createContents method.就我而言,我无法将参数传递给createContents方法。 My solution is using extends unlike the answer below.我的解决方案是使用扩展,与下面的答案不同。

private static class SomeContainer<E extends Object> {
    E e;
    E createContents() throws Exception{
        return (E) e.getClass().getDeclaredConstructor().newInstance();
    }
}

This is my example case in which I can't pass parameters.这是我无法传递参数的示例。

public class SomeContainer<E extends Object> {
    E object;

    void resetObject throws Exception{
        object = (E) object.getClass().getDeclaredConstructor().newInstance();
    }
}

Using reflection create run time error, if you extends your generic class with none object type.如果使用无对象类型扩展泛型类,则使用反射会创建运行时错误。 To extends your generic type to object convert this error to compile time error.要将泛型类型扩展为对象,请将此错误转换为编译时错误。

Use the TypeToken<T> class:使用TypeToken<T>类:

public class MyClass<T> {
    public T doSomething() {
        return (T) new TypeToken<T>(){}.getRawType().newInstance();
    }
}

I thought I could do that, but quite disappointed: it doesn't work, but I think it still worths sharing.我以为我可以这样做,但很失望:它不起作用,但我认为它仍然值得分享。

Maybe someone can correct:也许有人可以纠正:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface SomeContainer<E> {
    E createContents();
}

public class Main {

    @SuppressWarnings("unchecked")
    public static <E> SomeContainer<E> createSomeContainer() {
        return (SomeContainer<E>) Proxy.newProxyInstance(Main.class.getClassLoader(),
                new Class[]{ SomeContainer.class }, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Class<?> returnType = method.getReturnType();
                return returnType.newInstance();
            }
        });
    }

    public static void main(String[] args) {
        SomeContainer<String> container = createSomeContainer();

    [*] System.out.println("String created: [" +container.createContents()+"]");

    }
}

It produces:它产生:

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
    at Main.main(Main.java:26)
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Line 26 is the one with the [*] .第 26 行是带有[*]

The only viable solution is the one by @JustinRudd唯一可行的解​​决方案是@JustinRudd

An imporovement of @Noah's answer. @Noah 答案的改进。

Reason for Change造成改变的原因

a] Is safer if more then 1 generic type is used in case you changed the order. a]如果您更改顺序,则使用超过 1 个泛型类型会更安全。

b] A class generic type signature changes from time to time so that you will not be surprised by unexplained exceptions in the runtime. b]类的泛型类型签名会不时更改,因此您不会对运行时中无法解释的异常感到惊讶。

Robust Code健壮的代码

public abstract class Clazz<P extends Params, M extends Model> {

    protected M model;

    protected void createModel() {
    Type[] typeArguments = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments();
    for (Type type : typeArguments) {
        if ((type instanceof Class) && (Model.class.isAssignableFrom((Class) type))) {
            try {
                model = ((Class<M>) type).newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Or use the one liner或使用一个班轮

One Line Code一行代码

model = ((Class<M>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1]).newInstance();

what you can do is -你能做的是——

  1. First declare the variable of that generic class首先声明该泛型类的变量

    2.Then make a constructor of it and instantiate that object 2.然后创建它的构造函数并实例化该对象

  2. Then use it wherever you want to use it然后在任何你想使用的地方使用它

example-例子-

1 1

private Class<E> entity;

2 2

public xyzservice(Class<E> entity) {
        this.entity = entity;
    }



public E getEntity(Class<E> entity) throws InstantiationException, IllegalAccessException {
        return entity.newInstance();
    }

3. 3.

E e = getEntity(entity); E e = getEntity(entity);

You can achieve this with the following snippet:您可以使用以下代码段实现此目的:

import java.lang.reflect.ParameterizedType;

public class SomeContainer<E> {
   E createContents() throws InstantiationException, IllegalAccessException {
      ParameterizedType genericSuperclass = (ParameterizedType)
         getClass().getGenericSuperclass();
      @SuppressWarnings("unchecked")
      Class<E> clazz = (Class<E>)
         genericSuperclass.getActualTypeArguments()[0];
      return clazz.newInstance();
   }
   public static void main( String[] args ) throws Throwable {
      SomeContainer< Long > scl = new SomeContainer<>();
      Long l = scl.createContents();
      System.out.println( l );
   }
}

There are various libraries that can resolve E for you using techniques similar to what the Robertson article discussed.有各种库可以使用类似于 Robertson 文章中讨论的技术为您解析E Here's an implemenation of createContents that uses TypeTools to resolve the raw class represented by E:下面是createContents的一个实现,它使用TypeTools来解析由 E 表示的原始类:

E createContents() throws Exception {
  return TypeTools.resolveRawArgument(SomeContainer.class, getClass()).newInstance();
}

This assumes that getClass() resolves to a subclass of SomeContainer and will fail otherwise since the actual parameterized value of E will have been erased at runtime if it's not captured in a subclass.这假设 getClass() 解析为 SomeContainer 的子类,否则将失败,因为如果 E 的实际参数化值未在子类中捕获,则在运行时将被删除。

Here's an implementation of createContents that uses TypeTools to resolve the raw class represented by E :下面是createContents的一个实现,它使用TypeTools来解析由E表示的原始类:

E createContents() throws Exception {
  return TypeTools.resolveRawArgument(SomeContainer.class, getClass()).newInstance();
}

This approach only works if SomeContainer is subclassed so the actual value of E is captured in a type definition:这种方法仅在SomeContainer是子类化的情况下才有效,因此E的实际值在类型定义中被捕获:

class SomeStringContainer extends SomeContainer<String>

Otherwise the value of E is erased at runtime and is not recoverable.否则 E 的值在运行时被擦除并且不可恢复。

return   (E)((Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();

Here is an improved solution, based on ParameterizedType.getActualTypeArguments , already mentioned by @noah, @Lars Bohl, and some others.这是一个改进的解决方案,基于ParameterizedType.getActualTypeArguments ,@noah、@Lars Bohl 和其他一些人已经提到过。

First small improvement in the implementation.实施中的第一个小改进。 Factory should not return instance, but a type.工厂不应该返回实例,而是一个类型。 As soon as you return instance using Class.newInstance() you reduce a scope of usage.一旦您使用Class.newInstance()返回实例,您就会减少使用范围。 Because only no-arguments constructors can be invoke like this.因为只有无参数构造函数才能像这样调用。 A better way is to return a type, and allow a client to choose, which constructor he wants to invoke:更好的方法是返回一个类型,并允许客户端选择他想要调用的构造函数:

public class TypeReference<T> {
  public Class<T> type(){
    try {
      ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
      if (pt.getActualTypeArguments() == null || pt.getActualTypeArguments().length == 0){
        throw new IllegalStateException("Could not define type");
      }
      if (pt.getActualTypeArguments().length != 1){
        throw new IllegalStateException("More than one type has been found");
      }
      Type type = pt.getActualTypeArguments()[0];
      String typeAsString = type.getTypeName();
      return (Class<T>) Class.forName(typeAsString);

    } catch (Exception e){
      throw new IllegalStateException("Could not identify type", e);
    }

  }
}

Here is a usage examples.这是一个使用示例。 @Lars Bohl has shown only a signe way to get reified geneneric via extension. @Lars Bohl 只展示了一种通过扩展获得具体化泛型的方法。 @noah only via creating an instance with {} . @noah 仅通过使用{}创建实例。 Here are tests to demonstrate both cases:以下是演示这两种情况的测试:

import java.lang.reflect.Constructor;

public class TypeReferenceTest {

  private static final String NAME = "Peter";

  private static class Person{
    final String name;

    Person(String name) {
      this.name = name;
    }
  }

  @Test
  public void erased() {
    TypeReference<Person> p = new TypeReference<>();
    Assert.assertNotNull(p);
    try {
      p.type();
      Assert.fail();
    } catch (Exception e){
      Assert.assertEquals("Could not identify type", e.getMessage());
    }
  }

  @Test
  public void reified() throws Exception {
    TypeReference<Person> p = new TypeReference<Person>(){};
    Assert.assertNotNull(p);
    Assert.assertEquals(Person.class.getName(), p.type().getName());
    Constructor ctor = p.type().getDeclaredConstructor(NAME.getClass());
    Assert.assertNotNull(ctor);
    Person person = (Person) ctor.newInstance(NAME);
    Assert.assertEquals(NAME, person.name);
  }

  static class TypeReferencePerson extends TypeReference<Person>{}

  @Test
  public void reifiedExtenension() throws Exception {
    TypeReference<Person> p = new TypeReferencePerson();
    Assert.assertNotNull(p);
    Assert.assertEquals(Person.class.getName(), p.type().getName());
    Constructor ctor = p.type().getDeclaredConstructor(NAME.getClass());
    Assert.assertNotNull(ctor);
    Person person = (Person) ctor.newInstance(NAME);
    Assert.assertEquals(NAME, person.name);
  }
}

Note: you can force the clients of TypeReference always use {} when instance is created by making this class abstract: public abstract class TypeReference<T> .注意:您可以强制TypeReference的客户端在创建实例时始终使用{} ,方法是使此类抽象: public abstract class TypeReference<T> I've not done it, only to show erased test case.我没有这样做,只是为了显示擦除的测试用例。

Note that a generic type in kotlin could come without a default constructor.请注意,kotlin 中的泛型类型可能没有默认构造函数。

 implementation("org.objenesis","objenesis", "3.2")

    val fooType = Foo::class.java
    var instance: T = try {
        fooType.newInstance()
    } catch (e: InstantiationException) {
//            Use Objenesis because the fooType class has not a default constructor
        val objenesis: Objenesis = ObjenesisStd()
        objenesis.newInstance(fooType)
    }

I was inspired with Ira's solution and slightly modified it.我受到了 Ira 解决方案的启发并对其进行了轻微修改。

abstract class SomeContainer<E>
{
    protected E createContents() {
        throw new NotImplementedException();
    }

    public void doWork(){
        E obj = createContents();
        // Do the work with E 
     }
}

class BlackContainer extends SomeContainer<Black>{
    // this method is optional to implement in case you need it
    protected Black createContents() {
        return new Black();
    }
}

In case you need E instance you can implement createContents method in your derived class (or leave it not implemented in case you don't need it.如果你需要E实例,你可以在你的派生类中实现createContents方法(或者不实现它,以防你不需要它。

As you mentioned, you can't get an instance from generics. IMO, you have to change the design and make use of FACTORY METHOD design pattern.正如您提到的,您无法从 generics 获取实例。IMO,您必须更改设计并使用 FACTORY METHOD 设计模式。 In this manner you don't need your class or method to be generics:通过这种方式,您不需要 class 或方法为 generics:

class abstract SomeContainer{
    Parent execute(){
        return method1();
    }
    
    abstract Parent method1();
}


class Child1 extends Parent{
    Parent method1(){
        return new Parent();
    } 
} 

class Child2 extends Parent{
    Parent method1(){
        return new Child2();
    } 
} 

As you said, you can't really do it because of type erasure.正如您所说,由于类型擦除,您无法真正做到这一点。 You can sort of do it using reflection, but it requires a lot of code and lot of error handling.您可以使用反射来完成它,但它需要大量代码和大量错误处理。

If you mean new E() then it is impossible.如果你的意思是new E()那么这是不可能的。 And I would add that it is not always correct - how do you know if E has public no-args constructor?我要补充一点,它并不总是正确的——你怎么知道 E 是否有公共无参数构造函数? But you can always delegate creation to some other class that knows how to create an instance - it can be Class<E> or your custom code like this但是您始终可以将创建委托给其他知道如何创建实例的Class<E> - 它可以是Class<E>或您的自定义代码,如下所示

interface Factory<E>{
    E create();
}    

class IntegerFactory implements Factory<Integer>{    
  private static int i = 0; 
  Integer create() {        
    return i++;    
  }
}

You can with a classloader and the class name, eventually some parameters.你可以用一个类加载器和类名,最后还有一些参数。

final ClassLoader classLoader = ...
final Class<?> aClass = classLoader.loadClass("java.lang.Integer");
final Constructor<?> constructor = aClass.getConstructor(int.class);
final Object o = constructor.newInstance(123);
System.out.println("o = " + o);

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

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