繁体   English   中英

如何在Java接口中使用泛型?

[英]How to use generics in a java interface?

我正在尝试使用泛型构建一个简单的接口,这是我正在尝试使用的代码:

public interface MyInterface<T>
{
   public ArrayList<T> items;
   //...
}

但是,从非静态上下文等访问静态变量T时出现错误。如何完成我想做的事情? 这是我设想使用实现此接口的类的方式:

MyInterface<SomeObject> foo = new MyInterfaceImpl<>();

for (SomeObject bar: foo.items)
{
     bar.someMethod();
}

是否可以通过接口指定?

接口中声明的所有变量都是默认的static和final,因此您的通用类型T不适用于ArrayList 因此它正在引发错误无法静态引用非静态类型T

摘自Java语言规范部分。 8.1.2

  • 在以下任何地方引用通用类C的类型参数是编译时错误:
  • C的静态成员的声明(第8.3.1.1节,第8.4.3.2节,第8.5.1节),或
  • 嵌套在C中的任何类型声明的静态成员的声明,或者
  • C的静态初始值设定项(第8.7节),或者
  • 嵌套在C中的任何类声明的静态初始化器。

主要问题是数据成员,在接口中声明时默认情况下是静态的。

静态数据成员不允许引用通用参数。 如果允许的话,这将破坏类型安全性,因为应该允许不同的实例具有不同的类型实参,但是静态成员由所有实例共享,因此不能将其链接到特定的类型实参。

基本上是一个接口描述能力(又名什么类可以做)不执行(实例又名如何实现这些功能)。

另一个stackoverflow问题

接口变量是静态的,因为不能单独实例化Java接口。 必须在不存在任何实例的静态上下文中分配变量的值。 final修饰符确保分配给接口变量的值是一个真正的常量,不能由程序代码重新分配。

您实际上真正需要的是一个抽象基类

class abstract Base<T> implements MyInterface<T> {
    //btw it's recommended that you use interfaces as the declaring type not implementations
    public List<T> items = new ArrayList<T>;
}

class MyInterfaceImpl<T> extends Base<T> {
   //...
}

抽象基类的优点是它们可以包含0%到100%的实现,包括公共/保护/私有实例字段。

按照Eyal的解释,执行以下操作:

public interface MyInterface<T> {
  Collection<T> getItems();
}

实现类将包含一个动态数据成员:

public class MyImpl<T> implements MyInterface<T> {
  private Collection<T> items;
  public Collection<T> getItems() { return items; }
}

您必须这样做:

MyInterface<SomeObject> foo = new MyInterfaceImpl<SomeObject>();

for (SomeObject bar: foo.items)
{
    bar.someMethod();
}

请注意,如果MyInterfaceImpl是通用的,或者不是通用的,则必须使用适当的类进行参数设置,因为在那里不需要括号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM