【发布时间】:2020-12-06 23:24:56
【问题描述】:
我在 Java 15 中有一个简单的 Runnable 实现。
package work.basil.example;
public class MonsterRunnable < Monster > implements Runnable
{
private final Monster monster;
// Constructor
public MonsterRunnable ( Monster monster )
{
this.monster = monster;
}
@Override
public void run ( )
{
this.monster.actOut(); // ???? Compiler error: Cannot resolve method 'actOut' in 'Monster'
}
}
我的 IDE (IntelliJ 2020.3) 中的编译器无法解析 this.monster.actOut(); 方法的 this.monster.actOut(); 行上的方法 actOut。
然而,该方法在接口上已明确定义,如下所示。
package work.basil.example;
public sealed interface Monster
permits Demon, Witch
{
String name ( ); // This getter method implemented implicitly by `record` in our concrete classes `Demon` & `Witch`.
public void actOut ( ); // ???? Method is declared, yet cannot be resolved in `Runnable`.
}
我的小演示应用正在使用 Java 15 预览功能 JEP 360: Sealed Classes (Preview) 和 JEP 384: Records (Second Preview)。但我看不出这可能会成为麻烦的根源。
我想上面的代码应该足够了。但我可以展示接口的一对实现,Demon 和 Witch。
package work.basil.example;
public record Demon(String name) implements Monster
{
@Override
public void actOut ( )
{
System.out.println( "This monster " + this.getClass().getSimpleName() + " named " + this.name + " buys a soul." );
}
}
……和……
package work.basil.example;
public record Witch(String name) implements Monster
{
@Override
public void actOut ( )
{
System.out.println( "This monster " + this.getClass().getSimpleName() + " named " + this.name + " casts a spell." );
}
}
最后,这里是 actOut 方法工作的演示 - 如果我在有问题的 run 方法中删除 this.monster.actOut(); 行。
package work.basil.example;
/**
* Hello world!
*/
public class MonterMash
{
public static void main ( String[] args )
{
System.out.println( "Hello World!" );
MonterMash monterMash = new MonterMash();
monterMash.demo();
}
private void demo ( )
{
Monster monster = new Witch( "Rowena" );
System.out.println( "monster = " + monster );
monster.actOut();
}
}
运行时:
世界你好!
怪物 = 女巫[name=Rowena]
这个名叫罗薇娜的怪物女巫会施法。
【问题讨论】:
-
问题是你使用 Monster 作为你的泛型类型。尝试使其不通用:
public class MonsterRunnable {或者如果它需要通用使用 T -
@sprinter 是的!删除泛型作品。将
public class MonsterRunnable < Monster > implements Runnable更改为public class MonsterRunnable implements Runnable会使编译器满意。但为什么?整个实验的实际目标是为Runnable实现声明一个泛型类型。请发布一个答案让我接受。 -
因为
Monster只使用了一个没有边界的泛型类型,所以它可以是任何东西。就像List<E>一样,E也可以是任何东西(这里你的Monster与E完全相同)。这就是为什么你应该很少对泛型类型使用实际的词,这可能会造成混淆。
标签: java interface compiler-errors runnable