Java泛型-参数化类与类型化方法
我猜这是一个重复的问题,但在浏览了大量相关问题后,我找不到匹配的问题。。。是的,蹩脚的借口;) 我目前正在为实现开发一个通用接口。 使用泛型的原因是为了支持接口,用户代码不需要向下转换到具体的实现,也就是说,用户可以决定是使用实现类还是使用公共接口。 当然,在没有泛型的情况下,返回类型缩小的效果与预期的一样 我的目标是最小化类用户的参数声明—请参阅main方法。在内部,泛型引用可能更复杂 所以我想要这样的东西: (为了简单起见,我没有使用Iterable接口,而是使用了另一个类型参数) /*更新:向类中添加了static,并删除了null定义,以实际运行示例*/Java泛型-参数化类与类型化方法,java,generics,inheritance,apache-poi,parameterized-types,Java,Generics,Inheritance,Apache Poi,Parameterized Types,我猜这是一个重复的问题,但在浏览了大量相关问题后,我找不到匹配的问题。。。是的,蹩脚的借口;) 我目前正在为实现开发一个通用接口。 使用泛型的原因是为了支持接口,用户代码不需要向下转换到具体的实现,也就是说,用户可以决定是使用实现类还是使用公共接口。 当然,在没有泛型的情况下,返回类型缩小的效果与预期的一样 我的目标是最小化类用户的参数声明—请参阅main方法。在内部,泛型引用可能更复杂 所以我想要这样的东西: (为了简单起见,我没有使用Iterable接口,而是使用了另一个类型参数) /*更新
public class GenericsTest {
static interface SlideShow {}
static class HSLFSlideShow implements SlideShow {}
static interface Notes<SS extends SlideShow> {}
static class HSLFNotes implements Notes<HSLFSlideShow> {}
static interface Slide<SS extends SlideShow> {
<N extends Notes<SS>> N getNotes();
<N extends Notes<SS>> void setNotes(N n);
}
// compile errors
static class HSLFSlide implements Slide<HSLFSlideShow> {
HSLFNotes notes = new HSLFNotes();
@Override
public HSLFNotes getNotes() { return notes; }
@Override
public void setNotes(HSLFNotes n) { notes = n; }
}
public static void main(String[] args) {
HSLFSlide s = new HSLFSlide();
HSLFNotes n = s.getNotes();
s.setNotes(n);
Slide<HSLFSlideShow> s2 = new HSLFSlide();
Notes<HSLFSlideShow> n2 = s2.getNotes();
}
}
公共类泛型测试{
静态界面幻灯片{}
静态类HSLFSlideShow实现SlideShow{}
静态接口注释{}
静态类HSLFNotes实现Notes{}
静态界面幻灯片{
N getNotes();
无效设置注释(N);
}
//编译错误
静态类HSLFSlide实现了Slide{
HSLFNotes=新的HSLFNotes();
@凌驾
public HSLFNotes getNotes(){return notes;}
@凌驾
公共void setNotes(HSLFNotes n){notes=n;}
}
公共静态void main(字符串[]args){
HSLFSlide s=新的HSLFSlide();
HSLFNotes n=s.getNotes();
s、 setNotes(n);
幻灯片s2=新的HSLFSlide();
Notes n2=s2.getNotes();
}
}
我可以让它和。。。但这似乎有点笨拙:
static interface Slide<SS extends SlideShow, N extends Notes<SS>> {
N getNotes();
void setNotes(N n);
}
static class HSLFSlide implements Slide<HSLFSlideShow,HSLFNotes> {
HSLFNotes notes = new HSLFNotes();
@Override
public HSLFNotes getNotes() { return notes; }
@Override
public void setNotes(HSLFNotes n) { notes = n; }
}
public static void main(String[] args) {
HSLFSlide s = new HSLFSlide();
HSLFNotes n = s.getNotes();
s.setNotes(n);
Slide<HSLFSlideShow,HSLFNotes> s2 = new HSLFSlide();
Notes<HSLFSlideShow> n2 = s2.getNotes();
}
静态界面幻灯片{
N getNotes();
无效设置注释(N);
}
静态类HSLFSlide实现了Slide{
HSLFNotes=新的HSLFNotes();
@凌驾
public HSLFNotes getNotes(){return notes;}
@凌驾
公共void setNotes(HSLFNotes n){notes=n;}
}
公共静态void main(字符串[]args){
HSLFSlide s=新的HSLFSlide();
HSLFNotes n=s.getNotes();
s、 setNotes(n);
幻灯片s2=新的HSLFSlide();
Notes n2=s2.getNotes();
}
您如何在main方法中最小化所需的类型参数(最小值为JDK6)?尽管这似乎是一个答案,但请随意添加另一个选项:
public class GenericsTest {
static interface SlideShow {}
static class HSLFSlideShow implements SlideShow {}
static interface Notes<SS extends SlideShow> {}
static class HSLFNotes implements Notes<HSLFSlideShow> {}
static interface Slide<SS extends SlideShow> {
<N extends Notes<SS>> N getNotes();
<N extends Notes<SS>> void setNotes(N n);
}
static class HSLFSlide implements Slide<HSLFSlideShow> {
HSLFNotes notes = new HSLFNotes();
@SuppressWarnings("unchecked")
@Override
public HSLFNotes getNotes() {
return notes;
}
@Override
public <N extends Notes<HSLFSlideShow>> void setNotes(N n) {
notes = (HSLFNotes)n;
}
}
public static void main(String[] args) {
HSLFSlide s = new HSLFSlide();
HSLFNotes n = s.getNotes();
s.setNotes(n);
Slide<HSLFSlideShow> s2 = new HSLFSlide();
Notes<HSLFSlideShow> n2 = s2.getNotes();
}
}
公共类泛型测试{
静态界面幻灯片{}
静态类HSLFSlideShow实现SlideShow{}
静态接口注释{}
静态类HSLFNotes实现Notes{}
静态界面幻灯片{
N getNotes();
无效设置注释(N);
}
静态类HSLFSlide实现了Slide{
HSLFNotes=新的HSLFNotes();
@抑制警告(“未选中”)
@凌驾
公共HSLFNotes getNotes(){
回条;
}
@凌驾
公共作废集注(N){
注释=(HSLFNotes)n;
}
}
公共静态void main(字符串[]args){
HSLFSlide s=新的HSLFSlide();
HSLFNotes n=s.getNotes();
s、 setNotes(n);
幻灯片s2=新的HSLFSlide();
Notes n2=s2.getNotes();
}
}
据我所知,这里没有理由使用泛型方法。用非泛型方法重写泛型方法可能与您认为的方法不同。我已经讨论过这个问题了。(另请参见。)
泛型方法的类型由调用站点决定。出于向后兼容性的原因,允许将其重写为非泛型。人们仍然可以来做如下事情:
HSLFSlide slide = ...;
Slide<HSLFSlideShow> oops = slide;
// perfectly legal
// probably throws a ClassCastException somewhere
oops.<SomeOtherNotes>set(new SomeOtherNotes());
interface Slide<SS extends SlideShow> {
Notes<SS> getNotes();
void setNotes(Notes<SS> n);
}
class HSLFSlide implements Slide<HSLFSlideShow> {
Notes<HSLFSlideShow> notes = new HSLFNotes();
@Override
public Notes<HSLFSlideShow> getNotes() { return notes; }
@Override
public void setNotes(Notes<HSLFSlideShow> n) { notes = n; }
}
interface Slide<N extends Notes<?>> {
N getNotes();
void setNotes(N n);
}
class HSLFSlide implements Slide<HSLFNotes> {
HSLFNotes notes = new HSLFNotes();
@Override
public HSLFNotes getNotes() { return notes; }
@Override
public void setNotes(HSLFNotes n) { notes = n; }
}
以及问题中的工作示例:
interface Slide<SS extends SlideShow, N extends Notes<SS>> {…}
class HSLFSlide implements Slide<HSLFSlideShow, HSLFNotes> {…}
界面幻灯片{…}
类HSLFSlide实现幻灯片{…}
这实际上很好。我相信你不能,至少只要你希望它是类型安全的。Java中的类型系统相当冗长,遗憾的是没有其他一些语言中的类型系统灵活。这是因为Java中的泛型是后来添加的,提供向后兼容性对语言设计者来说很重要。首先,非常感谢-您的回答/链接让我对泛型有了更多的了解,我仍然不时地遇到一些理解上的问题@“完全合法”:我已经认为这样的事情是可能的,但我不知道语法。我想最后我必须决定,我想在多大程度上实现类型安全…@“这里没有理由使用泛型方法”:是的,我已经尝试删除所有泛型声明,但它们不知何故又开始悄悄进入,也许我牺牲了列表/iterable处理,然后返回数组。。。完成后,我将查看用户代码并决定它看起来有多可怕;)@“典型方式”:将有特定于实现的方法,我不希望用户在决定处理实现引用时贬低引用@“另一种方式/工作示例”:当我想稳妥起见,我认为工作示例最好,它锁定了混合实现的可能性
interface Slide<SS extends SlideShow, N extends Notes<SS>> {…}
class HSLFSlide implements Slide<HSLFSlideShow, HSLFNotes> {…}