因此,我可以遍历这段代码,这是Java中通用方法的演示:
public static <T> T addAndReturn(T element, Collection<T> collection){
collection.add(element);
return element;
}
....
String stringElement = "stringElement";
List<String> stringList = new ArrayList<String>();
String theElement = addAndReturn(stringElement, stringList);
但是我不想返回元素,而是要发回整个集合对象。我尝试了几种给定返回类型作为Collection的方法,但是以某种方式不起作用,
public static <T> Collection<T> addAndReturn(T element, Collection<T> collection) {
collection.add(element);
System.out.println(collection);
return collection;
}
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
String stringElement = "stringElement";
List<String> strList = new ArrayList<String>();
ArrayList<String> strRes = addAndReturn(stringElement, strList);
System.out.println(strRes);
}
并收到此错误:
Main.java:22:错误:不兼容的类型:没有类型的实例 存在变量T,以便Collection符合 ArrayList ArrayList strRes = addAndReturn(stringElement,strList); ^其中T是类型变量: T扩展了在方法addAndReturn(T,Collection)1中声明的对象错误
有人可以帮助我解决问题吗?
代码示例来自Jenkov.com
答案 0 :(得分:5)
根据OP的评论进行编辑:必须理解ArrayList
源自Collection。因此,当方法的接口返回Collection<T>
时,当然,您只能将结果分配给Collection
,而不能分配给List / ArrayList。您不知道传入List实例的事实。编译器只会看到Collection回来了!
回到第一个问题:您的代码正在返回添加的元素:
public static <T> T addAndReturn(T element, Collection<T> collection){
collection.add(element);
return element;
}
只需更改签名和返回的内容:
public static <T> Collection<T> addAndReturn(T element, Collection<T> collection){
collection.add(element);
return collection;
}
完成了吗?不是。
如:这不是一个好习惯。返回以参数形式出现的内容会很快导致代码阅读者感到困惑。使读者感到困惑是一件不好的事情。
除此之外:整个方法本身就是伪造的本身,因为该方法的调用者也可以只写:
thatCollection.add(thatElement);
自己。您的方法不会为上述方法添加任何值!对于读者而言,这相当模糊。
为什么有人要写:
addAndReturn(someX, listOfXes);
代替
listOfXes.add(someX);
如果要这样做:
addAndReturn(someX, listOfXes).addAndReturn(someOtherX, listOfXes);
您宁愿去
listOfXes.addAll(Arrays.asList(someX, someOtherX));
例如。不要为可以使用标准库调用处理的事情发明“实用程序”。
答案 1 :(得分:1)
这是您要寻找的吗?
public static <T> Collection<T> addAndReturn(T element, Collection<T> collection) {
collection.add(element);
return collection;
}
答案 2 :(得分:1)
类似于下面的清单。
public static <T> Collection<T> addAndReturn(final T element, final Collection<T> collection) {
collection.add(element);
return collection;
}
@Test
public void test() {
final String stringElement = "stringElement";
final List<String> stringList = new ArrayList<String>();
final List<String> nextList = (List<String>) addAndReturn(stringElement, stringList);
assertThat(nextList.get(0), is(equalTo(stringElement)));
}
您只需关心正确的返回参数Collection<T>
。 如果想要从子类或列表final List<String> nextList = (List<String>) addAndReturn(stringElement, stringList);
之类的接口中进行转换,则可能必须强制转换。
答案 3 :(得分:1)
错误消息指向此行:
ArrayList<String> strRes = addAndReturn(stringElement, strList);
这是在告诉您(使用非Compilerese普通英语),它找不到允许该分配发生的通用类型。
您的方法返回一个Collection<T>
(在这种情况下为Collection<String>
)。 Collection<String>
不是ArrayList<String>
的子类型,因此,您不允许将Collection<String>
类型的对象分配给ArrayList<String>
类型的字段。您的方法返回一个Collection<String>
,所以最简单的解决方法是将其分配给类型为Collection<String>
的字段:
Collection<String> strRes = addAndReturn(stringElement, strList);
或者,您可以使用局部变量类型推断(假设您使用的是Java的当前版本):
var strRes = addAndReturn(stringElement, strList);