我在util.TreeSet类中发现其中一个构造函数正在使用new TreeMap泛型类型调用另一个构造函数.
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
Run Code Online (Sandbox Code Playgroud)
什么new TreeMap<>意思?那相当于new TreeMap<?>?
前几天我正在审查其他人的代码,我遇到了引起一些担忧的问题.为了简化,我说我有一个通用的A类和一个抽象的B类.是否允许以下实例化,如果允许,为什么?
Object obj = new A<? extends B>();
Run Code Online (Sandbox Code Playgroud)
我个人从来没有见过像上面这样的实例化,虽然这样的声明如
A<? extends B> obj = null;
Run Code Online (Sandbox Code Playgroud)
肯定会持有.我总是在泛型中使用通配符来声明方法参数,所以我可能没有经验.
我有这门课
public class Tree<T> {
//List of branches for this tree
private List<Tree<? super T>> branch = new ArrayList<Tree<? super T>>();
public Tree(T t){ this.t = t; }
public void addBranch(Tree< ? super T> src){ branch.add(src); }
public Tree<? extends T> getBranch(int branchNum){
return (Tree<? extends T>) branch.get(branchNum);
}
private T t;
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用此类创建一个变量
public static void main(String[] args){
Tree<? super Number> num2 = new Tree<? super Number>(2);
}
Run Code Online (Sandbox Code Playgroud)
它给了我这个错误
Cannot instantiate the type Tree<? super Number>
Run Code Online (Sandbox Code Playgroud) 我上课了
public class OrderedBox<T> {}
Run Code Online (Sandbox Code Playgroud)
编译器不允许像这样创建成员/局部变量.
OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();
List<? extends T> testItems2 = new ArrayList<? extends T>();
Run Code Online (Sandbox Code Playgroud)
它在运行时是可以理解的原因,它不能保证对象的类型(由T限制的上限)将被插入并且将违反类型安全.
但它允许创建像这样的成员/局部变量.为什么以及如何允许这个?
private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();
Run Code Online (Sandbox Code Playgroud)
注意:我在浏览http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html时有这个疑问
可能重复:
使用通配符
Generics通配符实例创建新的通用对象
但是这两个问题都提供了两个选项编译失败的原因.我无法理解为什么以及如何允许最后一个.
List<? extends Object> list = new ArrayList<? extends Object>();
Run Code Online (Sandbox Code Playgroud)
有没有人可以帮我解释为什么我不能在使用arraylist时将泛型扩展到Object?
我正在寻找一些如下所示的代码:
public class Parent<T is_or_extends Parent<T>> {
public T function() {
// do some stuff //
return correct();
}
public T correct() {
return (T) this;
}
}
Run Code Online (Sandbox Code Playgroud)
这样任何子类都可以访问其他父函数,但仍然是独立的类(没有将function()的返回值向上转换为Parent的实例).程序员也可以独立使用Parent类(因此可以创建Parent的实例而不使用function()向下转换返回对象)
执行:
public class Child extends Parent<Child> {}
Run Code Online (Sandbox Code Playgroud)
用法:
Child child = new Child(); // ok
Parent<Child> polymorph = new Child(); // ok
Parent<Parent> parent = new Parent<Parent>(); // ERROR!
Run Code Online (Sandbox Code Playgroud)
为了概述差异,这不是方法链的问题.相反,当父类接受子类的泛型时,它不能再单独用作类(使用上面的代码),因为new Parent<Parent>()不会编译(当用" is_or_extends" 替换" "时extends)
我的目标:
我想要实现的是父类,当扩展时,function()将返回子类的对象而不是父类.
我会使用泛型类型来告诉父类哪个子类调用了该函数,但是我不能再使用父类的对象而不会遇到异常.一个例子如下:
public static class Parent<T extends Parent<T>> {} …Run Code Online (Sandbox Code Playgroud)