希望在了解通用边界之后,我尝试了解通配符上限和下限。我的参考是: https: //docs.oracle.com/javase/tutorial/java/generics/wildcards.html 我发现有一句话我能理解:“通配符可以在多种情况下使用:作为参数、字段或局部变量; “字段和局部变量?无法想象。为什么如此重要的来源不通过一个简单的例子来强调它?
我试图了解 java 编译器用哪个引用来替换(同时擦除)“?”。也许我有一个很大的误解,并且会发生任何删除(因此以下所有示例都不相关)。在下面的例子中: 1.
public static void funcA (List<? extends Number>l)
Run Code Online (Sandbox Code Playgroud)
2.
public static void funcB(List<? super Integer>l)
Run Code Online (Sandbox Code Playgroud)
第二个示例和以下代码之间有区别吗: 3.
public static <T extends Integer> funcC(List<? extends T>l)
Run Code Online (Sandbox Code Playgroud)
示例2与下面的示例是否有不同: 4.
public static <T extends Integer> void funcC(List<T>l)
Run Code Online (Sandbox Code Playgroud) 也许我忽略了一些非常容易和明显的事情......
我有一个类似的方法接口
private void render(Collection<Object> rows);
Run Code Online (Sandbox Code Playgroud)
现在,我需要传递的对象是一个数组(来自枚举):
Module[] mods = Module.values();
widget.render(mods);
Run Code Online (Sandbox Code Playgroud)
当然这不起作用,但为什么这不起作用:
widget.render(Arrays.asList(mods))
Run Code Online (Sandbox Code Playgroud)
它将我的数组转换为Module的集合,而Module是一个对象......
在我的Android Studio项目中,我有简单的类结构:
public class P{}
public class A extends P{}
public class B extends P{}
Run Code Online (Sandbox Code Playgroud)
在另一个班级我有一个List:
private List<? extends P> data;
private List<A> listA;
private List<B> listB;
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试这样做时:
data = listA; //it's ok
data.addAll(listB); //it calls error
Run Code Online (Sandbox Code Playgroud)
Android Studio中的第二行是红色,错误是:
addAll(java.util.Collection<capture<? extends com.mydomain.P>>)
in List cannot be applied to (java.util.List<com.mydomain.subclass.B>)
Run Code Online (Sandbox Code Playgroud)
我怎么解决这个问题?
这可能听起来有点微不足道,但我真的无法找到问题的症结所在.
List<Dog> dogs = getListOfDogs();
List<Cat> cats = getListOfCats();
feed(dogs);
feed(cats);
public void feed(List<Animal> animals) {
// feed the animal:
// depending on the type of animal, I might want to give it
// different kind of food.
}
class Dog implements Animal { /**/ }
class Cat implements Animal { /**/ }
interface Animal { /**/ }
Run Code Online (Sandbox Code Playgroud)
我的上下文非常类似于上面描述的上下文.我们也假设getListOfDogs并且getListOfCats是固定的,并且没有办法在那一方采取行动.
当然,就像这样,这是一个非法的代码:feed只接受List<Animal>类型,而我只能List<Cat>和List<Dog>.
因为feed这两种动物几乎完全相同,除了食物的种类(我可以通过它来管理它instanceof),我想避免复制它,只是改变签名.
有没有办法超级投射两个名单?像这样的东西(这显然不正确):feed((List<Animal>) getListOfDogs());
public interface A {
int getA();
}
public class MyObj implements A {
public int getA(){
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果有地图: Map<? extends A, String> aMap = new HashMap<>();
我如何可以将添加MyObj到这个aMap?或者该如何成为该类MyObj以便它可以在此映射中工作
我有一个非常基本的问题.
下面的代码无法编译(假设Apple Extends Fruit):
List<? extends Fruit> numbers = new ArrayList<>();
numbers.add(new Apple()); //compile time error
Run Code Online (Sandbox Code Playgroud)
当阅读为什么不,我理解的话,但不是概念:).
让我们假设第一个Fruit不是抽象类.我理解,因为我们正在处理多个子类型,所有这些都扩展了Fruit.据说因为我们无法确定水果的确切类型,所以我们不能在收集中加入任何东西.有几件我不明白的事情:
1)显然我们无法知道哪种水果让我感到困惑.在迭代集合时,我们不能通过typeof或其他instanceof检查告诉特定类型吗?
2)假设Fruit是一个具体的类,为什么我们不允许添加Fruit的实例?这似乎是有道理的,因为你至少知道Fruit的API.即使你不知道Fruit的确切子类型,至少你可以在Fruit()上调用标准方法.
我觉得这应该是相当明显的,但有些东西不是为了点击我.任何帮助都很感激.谢谢!
我正在查看 Java 的 TheAlgorithms 存储库,首先找到了这个: https: //github.com/TheAlgorithms/Java/blob/master/Searches/SearchAlgorithm.java。我明白了<T extends Comparable<T>>,但我不知道这意味着什么。我只了解一点关于泛型的知识,并且我知道语法与参数类型边界有关,但是如果有人能够澄清这与Comparable<T>和 是什么Comparable<T>有什么关系,那就太好了。
这个论坛上还有一些与我的类似的其他问题,涉及实施<T extends Comparable<T>>,但答案并没有真正澄清是什么Comparable<T>。
我有以下代码:
class ParametrizedObject<T> {...}
...
if (unknownObject instanceof ParametrizedObject) {
ParametrizedObject casted = (ParametrizedObject) unknownObject;
}
Run Code Online (Sandbox Code Playgroud)
此代码触发 rawtypes 警告。有没有办法/最佳实践来避免它?
注意:该类ParametrizedObject是框架的一部分,我无法更改它。
我正在浏览 java 8 中引入的 Predicate 类,它是函数式接口。Predicate 类中有一个方法和方法,用于将多个谓词组合成一个。
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了 Java 中 PECS 的概念,但仍然无法理解为什么在 Predicate 的情况下我们使用? super T. Java 程序员如何决定它将成为消费者而不是生产者。
我的意思是为什么不允许出现编译错误的行:
public class PredicateExample {
public static void main(String[] args) {
Predicate<Number> pred = n -> n.intValue() > 2;
Predicate<Integer> predInt = n -> n > 3;
//Compile error
//pred.and(predInt);
Predicate<Object> predObj = o -> Integer.parseInt(o.toString()) > 4;
pred.and(predObj); //Valid statement
Number n = new …Run Code Online (Sandbox Code Playgroud) public class Test {
public class A {}
public class B extends A {}
public class C extends B {}
public void testContraVariance(List<? super B> myBlist) {
B b = new B();
C c = new C();
myBlist.add(b);
myBlist.add(c);
A a = myBlist.get(0); // does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
如果 myBlist 接受 B 的超类型,这意味着 B 或 up,那么为什么还可以像中那样向它添加一个子类型myBlist.add(c)?
java ×10
generics ×7
collections ×3
list ×2
android ×1
arrays ×1
casting ×1
comparable ×1
extends ×1
java-8 ×1
lambda ×1
object ×1
pecs ×1
type-erasure ×1
wildcard ×1