Java 通用接口扩展?

Java 通用接口扩展?,java,eclipse,generics,interface,Java,Eclipse,Generics,Interface,您好,我有一个关于通用接口的问题,如果有人能详细地向我解释答案,我将不胜感激 接口I public interface I <T> { void f (T a); } 公共接口I{ 无效f(ta); } 接口J public interface J <T extends I<T>>{ void g(T b); } 公共接口J{ 无效g(tb); } A类 public class A<T> implements J<T>{

您好,我有一个关于通用接口的问题,如果有人能详细地向我解释答案,我将不胜感激

接口I

public interface I <T> {
void  f (T a);
}
公共接口I{
无效f(ta);
}
接口J

public interface J <T extends I<T>>{
  void g(T b);
}
公共接口J{
无效g(tb);
}
A类

public class A<T> implements J<T>{
    public void g(T b) {

    }
}
公共类A实现J{
公共空间g(T b){
}
}
类A中的代码将给出一个错误。 你能解释一下为什么它会出错吗

A类修复

public class A<T extends I<T>> implements J<T>{
    public void g(T b) {

    }
}
公共类A实现J{
公共空间g(T b){
}
}
有人能给我解释一下为什么这个代码会修复这个错误吗


提前感谢

这是因为您的
T
没有扩展/实现
I

使用同一个通用占位符常常令人困惑。试着这样看:

public interface I<TI> {
    void f(TI a);
}

public interface J<TJ extends I<TJ>> {
    void g(TJ b);
}

// Error:(17, 37) java: type argument TA is not within bounds of type-variable TJ
// i.e. This `TA` does NOT implement/extend J<TA extends I<TA>>
public class A<TA> implements J<TA> {
    public void g(TA b) {

    }
}

// Works fine because `TB extends I<TB>`
public class B<TB extends I<TB>> implements J<TB> {
    public void g(TB b) {

    }
}
公共接口I{
空隙f(TI-a);
}
公共接口J{
无效g(TJ b);
}
//错误:(17,37)java:type参数TA不在类型变量TJ的范围内
//也就是说,这个'TA'没有实现/扩展J
公共A级执行器J{
公共图书馆g(TA b){
}
}
//很好,因为我`
公共类B实现J{
公共部门g(TB b){
}
}
原因是
J
,因此,当您实现此接口时,需要为其提供扩展I的类T。但您不能这样编写
A实现J
。我猜这不是您想要的,因为它为T类创建了不必要的需求

所以我要改变的是:

第一:
J
更改为
J扩展I
。现在你有了更简单的J型。我想这就是你需要/想要的

第二:您应该实现所有方法,fi(tx)和fj(tx),所以就这么做吧

这是一个如何实现的工作示例。简单实用

public class MyClass {

    public static void main(String[] args) throws Exception {
        A a = new A<String>();
        a.fi("foo");
        a.fj("bar");
        return;
    }

    public interface I<T> {
        void  fi(T t);
    }

    public interface J<T> extends I<T> {
      void fj(T t);
    }

    public static class A<T> implements J<T> { 
        // it is static only to be accessible from main()
        public A() {
            // default constructor
        }

        public void fi(T t) {
            System.out.println("method from I, arg=" + b.toString());
        }

        public void fj(T t) {
            System.out.println("method from J, arg=" + b.toString());
        }
    }
}
method from I, arg=foo
method from J, arg=bar