15

以下に定義する 3 つの Java タイプがあります。

Main.java:

import java.util.Arrays;
import java.util.List;

public class Main 
{
    private Object callFunction() 
    {
        OperationDefinitions func = OperationDefinitions.CONCATENATE;
        List<Object> values = Arrays.asList(new Object[] {"ABC", "-", "DEF"});
        return func.call (values);
    }

    public static void main (String[] args)
    {
        Main main = new Main(); 
        System.out.println (main.callFunction());
    }
}

操作.java

import java.util.List;

public interface Operation
{
    abstract Object call(List<Object> params);
}

OperationDefinitions.java

import java.util.List;

enum OperationDefinitions implements Operation
{
    CONCATENATE() {
        public Object call(List<Object> params) 
        {
            StringBuilder builder = new StringBuilder();
            for (Object param : params) builder.append((String)param);
            return builder.toString();
        }
    },
    ;

}

(これは、Effective Java 2nd ed. Item 30 に記載されている例とほとんど同じです) 上記のコードは Eclipse で問題なくコンパイルおよび実行されますが、Sun javac では次のエラーが発生します。

Main.java:12: cannot find symbol
symbol  : method call(java.util.List<java.lang.Object>)
location: class OperationDefinitions
        return func.call (values);
                           ^
1 error

Main.java の 12 行目を から に変更return func.call(values);すると、正常return ((Operation)func).call(values)にコンパイルされます。さらに、3 つのタイプ (Operation、Main、および OperationDefinitions) を 1 つのメイン クラスの 3 つのサブクラスとしてまとめると、コンパイルも正常に行われます。

だから私は私の問題の回避策を持っていますが、なぜjavacはここでキャストを必要とするのですか? これは javac または eclipse のバグですか?

Sun javac 1.5.0_19 と 1.6.0_16 の両方を試しました

4

4 に答える 4

14

これはBug 6522780でしょうか?
またはバグ 6330385 ?
または、バグ 6724345 - JDK 7 で修正されたので、それをテストできます。

于 2009-10-02T10:16:49.250 に答える
10

Sunのjavacのバグである可能性があります。funcenum(それがenum実装されている場合でもOperation)であり、Enumクラスにはメソッドがありませんcall()。この問題を解決するには、割り当てを変更することをお勧めします。

Operation func = OperationDefinitions.CONCATENATE;

それはまたあなたが何を期待するかを明らかにするでしょう:ではなく操作enum。これenumは、可能なすべての操作(必要に応じてコンテナー)を収集するための便利な方法です。

于 2009-10-02T09:57:13.237 に答える
2

「Stephen Denne」が私たちに示したように、これはバグですが、新しいバージョンへの更新を行うことができない場合 (ただし、そうする必要があります) ... からインターフェイスを削除し、次のように列挙型にOperationDefinitionsメソッドを配置します。...call(...)

public abstract Object call(List params);

動作するはずです。

于 2013-12-04T17:16:58.413 に答える
0

これは実際にはバグだと思いjavacます。OperationDefinitionsインターフェイスを実装しているので、間違いなく abstract)メソッドcall(java.util.List)がありOperationます。また、すべての定数がこのインターフェイスの具体的な実装を提供するため、クラス定義は有効です。

これに部分的に関与している可能性があることの1つは、私の知る限り、インターフェースで定義されているすべてのメソッドはパブリックでなければならないということです。インターフェイスでデフォルトのアクセス修飾子を使用してメソッドを実際に定義した場合call、コンパイラがそれを拒否することを期待しますが、そうでない場合でも、問題が発生しても驚くことはありません。これがタイプミスの場合は問題ありませんが、コードでそのような場合は、パブリックとして宣言し、問題が解決するかどうかを確認してください。

于 2009-10-02T10:04:04.363 に答える