C#到Java:其中T:new()语法

时间:2010-04-12 01:35:36

标签: c# java generics

我正在将一些C#代码移植到Java上。我遇到了Syntax的问题​​,特别是new()。我理解在哪里类似于Java的泛型:T扩展了FOO。

如何在Java中复制new()参数?

"The new() Constraint lets the compiler know that any type argument supplied must have an accessible parameterless--or default-- constructor." - MSDN

即:

public class BAR<T> : BAR
       where T : FOO, new()

以下是我实施cletus解决方案的方法:

public class BAR<T extends FOO> extends ABSTRACTBAR {
    public BAR(T t) throws InstantiationException, IllegalAccessException{ 
        t.getClass().newInstance();
        this.value = t;
    }
}

3 个答案:

答案 0 :(得分:7)

你不能在Java中复制它,因为泛型在C#和Java之间根本不同。 Java使用类型擦除,因此泛型类型参数不会(大部分)在运行时保留。如果你想构造泛型类型参数的元素,那么你需要传入一个类实例:

public class Bar<T extends Foo> {
  private final Class<T> clazz;

  public class Bar(Class<T> clazz) {
    this.clazz = clazz;
  }

  public T newInstance() {
    return clazz.newInstance(); // this will throw checked exceptions
  }
}

编辑:只是为了解决泛型类型参数的运行时类型安全问题:显然,由于类型擦除,Java不会本机拥有它:没有运行时泛型类型参数的类型。但是有一个解决方案。您使用Collections.checkedList()

List<String> list = Collections.checkedList(new ArrayList<String>(),
                      String.class);

如果您尝试插入非String的内容,此集合现在会抛出异常。

答案 1 :(得分:0)

你做不到。 Java使用擦除实现泛型类型安全,并且不支持基于构造函数签名的类型,因此无法完全执行此操作并进行静态类型检查。

答案 2 :(得分:0)

希望这会有所帮助。请注意,这需要在创建新实例的时候出现一个无参数构造函数。


public class TypeStuff {

    private static final long serialVersionUID = 1L;

    // *** PUBLIC STATIC VOID MAIN ***
    public static void main(String[] args) {
        TypeStuff ts = new TypeStuff();
        ts.run();
    }

    // *** CONSTRUCTOR ***
    public TypeStuff () {
    }

    public void run() {
        Fruit banana = new Banana();

        Fruit dupe = newT(banana);
        System.out.println("dupe.getColor()=" + dupe.getColor());

        Fruit orange = new Orange();
        Fruit dupe2 = newT(orange);
        System.out.println("dupe2.getColor()=" + dupe2.getColor());
    }

    public <T extends Fruit> T newT(T fruit) {
        T dupe = null;
        try {
            Class clazz = fruit.getClass();
            dupe = (T) clazz.newInstance();
        } catch (Exception ex) {
        } finally {
            return dupe;
        }
    }

    interface Fruit {
        String getColor();
    }
    static class Banana implements Fruit {
        public Banana() {
        }
        @Override
        public String getColor() {
            return "Yellow";
        }
    }
    static class Orange implements Fruit {
        public Orange() {
        }
        @Override
        public String getColor() {
            return "Orange";
        }
    }


} // CLOSE CLASS.