【问题标题】:Trouble with Java generics in non-generic class非泛型类中的 Java 泛型问题
【发布时间】:2013-05-17 20:46:14
【问题描述】:
public class method
{
    private static class Foo
    {
        public void hello() { System.out.println("Foo"); }
    }

    private static class Bar
    {
        public void hello() { System.out.println("Bar"); }
    }

    private static <T> void hello(T typ)
    {
        typ.hello();
    }

    public static void main(String args[])
    {
        Foo foo = new Foo();
        Bar bar = new Bar();
        hello(foo);
        hello(bar);
    }
}

我在这里查看了有关泛型的其他问题,但是尽管我在那里看到了所有内容并将其应用于我编写的代码,但我的 Java 代码仍然存在问题。我已经解决了上面代码中遇到的问题。当我尝试编译上面的 codd 时,出现以下错误:

method.java:15: error: cannot find symbol
        typ.hello();
           ^
  symbol:   method hello()
  location: variable typ of type T
  where T is a type-variable:
    T extends Object declared in method <T>hello(T)

这可能是因为我想用通用的东西做一些他们没有设计做的事情,但根据我对文档的理解,这应该可行。当然,我阅读文档的想法是我可以做这样的事情,这肯定会影响我对它的理解。

谢谢

【问题讨论】:

  • 我真的想复制 C++ 模板化成员函数 template hello(T typ) { }
  • 如果我理解你的问题,你有两个接口 Foo 和 Bar。两个接口都有一个名为 hello() 的方法。您想创建一个类似 private static void hello(T typ) 的方法,其中 T 是 Foo 或 Bar。我做对了吗?

标签: java generics methods


【解决方案1】:

这是你的问题:

private static <T> void hello(T typ)

T 不会扩展任何实现名为“Hello”的方法的东西。

改为

 private static <T extends ClassThatHasHello> void hello(T type)

和班级:

 public class ClassThatHasHello {
      public void hello() { }
 }

【讨论】:

  • 我明白了,但在这种情况下,我有多个课程
  • 我真的想复制 C++ 模板化的成员函数 template hello(T typ) { }
  • 没关系,ClassThatHasHello 使用接口代替类即可。让你的多个类实现它
【解决方案2】:

您将 T 定义为 Object 的子类型。没有任何类型限制。对象没有hello() 方法

你可以为Foo and Bar然后&lt;T extends SuperType&gt;创建一个接口或超类型

【讨论】:

  • 超类型可能会起作用,因为我正在尝试为我没有编写的 2 个类编写泛型,每个类都有相同的方法
  • 所以你有 4 个类 A、B、C、D 都有hello(),你创建了一个超类型(抽象类/接口/普通类)S 它也有hello()。让A-D 扩展/实现S。然后你可以写&lt;T extends S&gt;,编译器不会抱怨typ.hello()
  • 不幸的是我没有写 Foo 或 Bar (它们实际上是接口,不像我在这里展示的那样——但错误是一样的
  • 然后向我们展示您的真实课程。我想我在回答+评论中解释得足够清楚了。如果它仍然不起作用,请显示您的相关代码。
  • downvote 可以,但请发表评论,以便我了解它为什么不好。谢谢。
【解决方案3】:

您需要使用interface。这有效:

private interface Hello {
  public void hello();
}

private static class Foo implements Hello {
  @Override
  public void hello() {
    System.out.println("Foo");
  }
}

private static class Bar implements Hello  {
  @Override
  public void hello() {
    System.out.println("Bar");
  }
}

private static <T extends Hello> void hello(T typ) {
  typ.hello();
}

public static void main(String args[]) {
  Foo foo = new Foo();
  Bar bar = new Bar();
  hello(foo);
  hello(bar);
}

【讨论】:

  • 不幸的是,我正在尝试为我没有编写的 2 个类编写泛型(实际上是接口,每个接口都扩展了其他接口,有一些重载)
  • 在这种情况下,您会问如何动态地使对象实现接口 - 您可能正在寻找 Proxy 类。
  • 我认为在 if 语句中复制/粘贴 2 个类中的每一个的 4 行更容易。我以为我可以省去复制/粘贴的双重维护,但与 C++ 相比,java 在这方面似乎存在不足,因为 C++ 可以作为模板方法使用
  • 你可能会后悔那个决定——这既不是威胁也不是承诺。 :)
  • 我很可能会这样做,但是添加一个完整的代理类实现来获得大约 4 行代码似乎更容易引起问题,因为它增加了复杂性。这个项目的架构还有很多不足之处:多个接口都实现了相同的方法,而无需扩展单个通用接口,并且在实现通用接口的地方,有几个接口重载了通用方法,因此扩展通用接口获胜不工作,因为它超载了
【解决方案4】:

您正在使用泛型,并且您正在尝试调用类型 T 的 hello 方法,但您不知道那是什么类型。如果您确定它有 hello 方法,请使用强制转换

【讨论】:

  • 我不认为投射在这里会起作用,因为我要通过 2 个不同的课程,我不知道它是哪一个
  • 如果两者都有 hello 方法,你可以创建一个接口,让它们实现它然后强制转换为接口
  • 它们已经是接口了。我只是想避免大量的复制粘贴,因为它们都实现了我必须调用的相同方法,并提供完全相同的参数。看起来唯一的解决方案是复制/粘贴我想念 C++ :-(
  • 不,它不是唯一的解决方案,我不明白你为什么不能使用铸造?
  • 作为他们都实现的接口
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
相关资源
最近更新 更多