[英]Java generics: matching the type of a parameter
我將如何修改它,使生成的Collection(newNodes)與傳入的Collection(節點)具有相同的類型?
public void setNodes(Collection<NodeInfo> nodes) {
Collection<NodeInfo> newNodes = new TreeSet<NodeInfo>();
for (NodeInfo ni: nodes) {
newNodes.add(ni.clone());
}
}
我懷疑那是...
public void setNodes(<T extends Collection<NodeInfo>> nodes) {
Collection<NodeInfo> newNodes = new T<NodeInfo>()
這可能嗎?
關閉,但沒有雪茄。 如果我了解您想做什么,您的方法應如下所示:
public <T extends NodeInfo> void setNodes(Collection<T> nodes) {
Collection<T> newNodes = new TreeSet<T>();
for(T t : nodes) {
newNodes.add(t);
}
}
不幸的是,用Java編寫它是不可能的。 如果需要此效果,則有幾種選擇:
如果您要針對特定種類的集合進行優化,則可以使用instanceof
check來檢測它。 (例如,Guava庫經常這樣做以檢測不可變的集合並進行特殊處理。)
如果您確實只需要填充一個集合,則可以要求呼叫者為您提供一個集合。
public <C extends Collection<NodeInfo>> void setNodes(C nodes, C newNodes) {
for (NodeInfo ni : nodes) {
newNodes.add(ni);
}
}
如果需要根據需要進行任意數量的這些集合的功能,則可以定義一個工廠接口並使調用者提供它的一個實例:
interface Factory<C extends Collection<NodeInfo>> {
C newCollection();
}
public <C extends Collection<NodeInfo>> void setNodes(C nodes, Factory<C> factory) {
C newNodes = factory.newCollection();
for (NodeInfo ni : nodes) {
newNodes.add(ni);
}
}
不幸的是,您無法在Java中進行new T
:由於泛型是通過類型擦除在Java中實現的,所以由類型參數提供的類型信息只是靜態可用的信息,即在運行時不再可用。 因此,Java不允許對象的通用創建(請參閱Angelika Lange的Generics FAQ )。
或者,您可以使用:
Class<T>
對象作為參數使類型在運行時可用 void setNodes(Collection<NodeInfo> nodes, Collection<NodeInfo> newNodes)
ArrayList<NodeInfo>
深度克隆nodes
,例如使用克隆庫 :
Cloner cloner = new Cloner();
@SuppressWarnings(“ unchecked”) Collection<NodeInfo> newNodes = cloner.deepClone(nodes);
注意,JDK中的許多Collection
實現本身都實現了Cloneable
。 一種“盡力而為”的方法可能是這樣的:
public Collection<NodeInfo> setNodes(Collection<NodeInfo> nodes) throws CloneNotSupportedException {
Collection<NodeInfo) newNodes;
if (nodes instanceof Cloneable)
newNodes = (Collection<NodeInfo>) newNodes.clone();
else
// Fallback in case we have a non-cloneable collection
newNodes = new TreeSet<NodeInfo>();
newNodes.clear();
for (NodeInfo ni: nodes) {
newNodes.add(ni.clone());
}
return newNodes;
}
對於許多輸入,這將返回相同的集合,但是如果它不能做得更好,則會退回到默認情況下返回TreeSet
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.