- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下代码:
// ...
public class BaseClass
{
public BaseClass (int theParam)
{
// ...whatever...
}
}
public class DerivedType
{
// ...Content does not matter...
}
// ...elsewhere:
public <ElemType extends BaseClass> boolean doIt (ArrayList<ElemType> target)
{
ElemType newElem=new ElemType (5) ; // "Cannot instantiate this type"
// ...other code does not matter...
return true ;
}
// ..
如何在 doIt
中创建 ElemType
类型的实例?
显示的构造产生指示的错误。
ElemType.newInstance
不存在,这让我感到惊讶。
我几乎阅读了所有常见问题解答、答案和可通过 Google 搜索到的 Material ,但找不到任何有用的内容。
编辑:是的,我知道反射有其缺点,并且出于多种原因,它并不是最终的解决方案。问题不是“我应该做什么”,而是“我会怎么做”。
最佳答案
如上所述,泛型类型的类型删除不允许这样做。但你可以像这样实现你想要的:
public class BaseClass {
public BaseClass(int theParam) {
// ...whatever...
}
public BaseClass() {
}
}
public class DerivedType extends BaseClass {
}
现在 doIt() 方法获取类参数以供引用:
public <D extends BaseClass> boolean doIt (ArrayList<D> target, Class<D> c)
{
try {
D newElem = c.getDeclaredConstructor(int.class).newInstance(5);
} catch (Exception e) {}
// ...other code does not matter...
return true ;
}
你应该这样调用它:
ArrayList<DerivedType> testList = new ArrayList<DerivedType>();
testList.add(new DerivedType());
testList.add(new DerivedType());
doIt(testList, DerivedType.class);
希望有帮助:)
请注意,人们可能真的想搞点技巧,摆脱类参数并尝试以下操作:
public static <D extends BaseClass> boolean doIt (ArrayList<D> target)
{
try {
D newElem1 = ((Class<D>) ((ParameterizedType) target.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getDeclaredConstructor(int.class).newInstance(5);
} catch (Exception e) { e.printStackTrace();}
return true ;
}
}
事实上,我在第二次编辑之前也是这么想的:)但这会得到一个“java.lang.ClassCastException:sun.reflect.generics.reflectiveObjects.TypeVariableImpl无法转换为java.lang.Class “正如您提到的异常(由于忽略了 catch 语句,我没有看到它)。简而言之,Java 运行时系统不存储参数化类型(有利于向后兼容;因此将来可能会改变)。
所以,看起来如果不“接触”某些类就不可能实现。
但是,除了提到的方法之外,我还可以想到另外两件事。首先,如果 BaseClass 和 DerivedType 'D' 类都实现了 clone() 方法,则可以从数组中获取对象的克隆,然后使用它:
D o = target.get(0);
D oNew = (D)((BaseClass)o).clone();
target.add(oNew);
多态性将处理剩下的事情:)
第二个不是真正的“解决方案”,但如果您想要的只是按类型参数化的对象数组的新实例,则可以使用第二个。类型删除仅发生在参数化类型上,但不会发生在基本数组上(数组在 JVM 中是具体化的)。因此,如果我们可以自由地更改方法的签名并且可以使用数组,那么以下内容将起作用:
public <D extends BaseClass> boolean doIt(D[] target) {
try {
D newD = (D) (target.getClass().getComponentType().getConstructor(int.class).newInstance(8));
target[0] = newD;
// The following is optional, if we want to work with Collections internally
List<D> l = new ArrayList<D>(Arrays.asList(target));
l.add(newD);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
注意:如果我们无法引入新参数, super 类型标记将无法解决此问题。如果我错了,请纠正我。
关于java - 如何在 Java 中实例化泛型方法参数的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9689325/
我是一名优秀的程序员,十分优秀!