我有一个如下定义的示例类:
public class FooBar {
void method1(Foo foo){ // Should be overwritten
...
}
}
Run Code Online (Sandbox Code Playgroud)
后来,当我尝试这个:
FooBar fooBar = new FooBar(){
public String name = null;
@Override
void method1(Foo foo){
...
}
};
fooBar.name = "Test";
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,说明名称字段不存在.为什么?
我想声明的是包含将返回实现双方的事情列表的方法的接口Comparator<Object>和Action,即
<T extends Comparator<Object> & Action> List<T> getThings();
Run Code Online (Sandbox Code Playgroud)
编译很好,但是当我尝试调用这个方法时会出现问题.我希望能够这样做:
List<Action> things = getThings();
List<Comparator<Object>> things = getThings();
Run Code Online (Sandbox Code Playgroud)
当我尝试这样做时,我得到以下编译错误:
incompatible types; no instance(s) of type variable(s) T exist so that
java.util.List<T> conforms to java.util.List<javax.swing.Action>
found : <T>java.util.List<T>
required: java.util.List<javax.swing.Action>
Run Code Online (Sandbox Code Playgroud)
以下内容也不起作用:
List<? extends Action> things = getThings();
List<? extends Comparator<Object>> things = getThings();
Run Code Online (Sandbox Code Playgroud)
达到这种效果的另一种方法是创建一个扩展两个空的接口Comparator<Object>和Action并使用它作为返回类型,即
public interface ComparatorAction extends Comparator<Object>, Action { }
List<ComparatorAction> getThings();
Run Code Online (Sandbox Code Playgroud)
但我不想这样做.必须有办法做我想做的事,对吧?有任何想法吗?
谢谢!
PS我很难为这篇文章争取一个好头衔,所以随时可以改变它.
我有三个接口:
public interface Combinable<V> {
V add(V other);
}
public interface Sublistable<V> {
boolean hasSublist();
List<V> getSublist();
void setSublist(List<V> sublist);
}
public interface HasUniqueIdentifier {
String getUniqueIdentifier();
}
Run Code Online (Sandbox Code Playgroud)
和4个实现部分或全部这些接口的类:
public class Grandparent implements HasUniqueIdentifier,
Sublistable<Parent>,
Combinable<Grandparent>
{ List<Parent> sublist; ... }
public class Parent implements HasUniqueIdentifier,
Sublistable<Child>,
Combinable<Parent>
{ List<Child> sublist; ... }
public class Child implements HasUniqueIdentifier,
Sublistable<Grandchild>,
Combinable<Child>
{ List<Grandchild> sublist; ... }
public class Grandchild implements HasUniqueIdentifier,
Combinable<Grandchild>
{ }
Run Code Online (Sandbox Code Playgroud)
我想有一个执行以下操作的通用方法:
public <V, T extends HasUniqueIdentifier & …Run Code Online (Sandbox Code Playgroud) 根据Java Generics FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 ,类型参数不能以这种方式前向引用
<A extends B, B> // error
Run Code Online (Sandbox Code Playgroud)
但是没关系
<A extends List<B>, B> // ok
Run Code Online (Sandbox Code Playgroud)
这两个例子用最新的验证jdk 1.6.0_24.
我的问题是,在语言规范中,这是指定的,隐含的还是可扣除的(即如果它是不真实的,其他事情可能会爆炸).我找不到任何地方.
更新
在javac7中,它是允许的.直观地说,类型参数的顺序无关紧要; 类型系统要求类型变量之间没有循环依赖关系:<A extends B, B extends A>.以前,这可以通过禁止前向参考来保证.显然,javac 7经过改进以放宽排序,同时无论排序如何都能检测循环.
javac的推断T是String在方法f().语言规范中的哪些规则导致了这个结论?
<T> T g(){ return null; }
String f()
{
return g();
}
Run Code Online (Sandbox Code Playgroud) 如果我们有一个泛型类的变量,比如List,它应该是什么类型的?
List<Class> c1;
Run Code Online (Sandbox Code Playgroud)
要么
List<Class<?>> c2;
Run Code Online (Sandbox Code Playgroud)