0

次の例があります。

class bounds
{
  private StringBuilder str = new StringBuilder();

  public <Type> void add (Type value)
  {
    add_specific (value);
    str.append (String.format("%n"));
  }

  private <Type extends Number> void add_specific (Type value)
  {
    str.append (value);
  }

  public String toString () { return str.toString(); }

  public static void main (String[] args)
  {
    bounds test = new bounds();
    test.add (new Integer (42));
    System.out.print (test.toString());
  }
}

コンパイルしようとすると、次のエラーが発生します。

bounds.java:7: エラー: クラス境界のメソッド add_specific は、指定された型に適用できません。
    add_specific (値);
    ^
  必須: タイプ#1
  見つかった: タイプ#2
  理由: 推論された型が宣言された境界に準拠していません
    推測: タイプ#2
    境界: 数値
  ここで、Type#1、Type#2 は型変数です。
    Type#1 extends Number 宣言メソッド add_specific(Type#1)
    Type#2 extends メソッド add で宣言された Object(Type#2)
1 エラー

addこれは、メソッドに渡された引数の元の型が の本体で失われたように見えますadd。正しいadd_specificメソッドを選択できるようにするにはどうすれば型を保持できますか?

アップデート

理解しやすいと思ったので、例を単純化しました。しかし、ほとんどの人は、ジェネリック関数と特定関数が含まれている理由を理解していないように思えます。そこで、より高度な例を貼り付けます。おそらく、これにより理由がより明確になります。

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

class bounds
{
  private StringBuilder str = new StringBuilder();

  public <Type> void add (Type value)
  {
    add_specific (value);
    str.append (String.format("%n"));
  }

  private <Type extends Number> void add_specific (Type value)
  {
    str.append (value);
  }

  private void add_specific (String value)
  {
    str.append ('"');
    for (int i = 0; i < value.length(); i++) {
      char ch = value.charAt(i);
      switch (ch) {
      case '\\': str.append ("\\\\"); break;
      case '"': str.append ("\\\""); break;
      default: str.append (ch);
      }
    }
    str.append ('"');
  }

  private static DateFormat iso8601
    = new SimpleDateFormat("'\"'yyyy-MM-dd'T'HH:mm:ssZ'\"'");

  private void add_specific (Date date)
  {
    str.append (iso8601.format(date));
  }

  public String toString ()
  {
    return str.toString();
  }

  public static void main (String[] args)
  {
    bounds test = new bounds();

    test.add (new Integer (42));
    test.add ("42");
    test.add (new Date());

    System.out.print (test.toString());
  }
}

という汎用関数がありaddます。この汎用関数は汎用的な処理を行い、特定の関数を呼び出して特定の処理を行います。問題は、特定の関数を選択する型がジェネリック関数で失われることです。問題は、これを修正する方法です。ジェネリック関数の本体で適切な特定の関数を選択できるようにするには、ジェネリック関数をどのように作成する必要がありますか?

4

4 に答える 4

1

問題はこの部分です:

public <Type> void add (Type value)
{
   add_specific (value);
   ...
}

add_specific値は拡張するタイプである必要がありますが、それをNumber必要addとしない/保証しません。したがって、エラー。

addそれを修正するには、を使用するように変更する必要がありますが<Type extends Number>、それがあなたが望んでいることとは思えません。私には設計エラーのように思えますadd_specific。より一般的な外観を呼び出す必要がaddあり、その逆ではありません。

ところで、John Skeet が既に言ったように、バグを見つけやすく、コードを読みやすくするために、コーディング規則を遵守してください。

于 2013-10-08T15:16:28.153 に答える
0

valueメソッド内の参照addは必ずしもNumber

これを解決するには:

addメソッドを次のように変更します。

public <Type extends Number> void add (Type value)
{

}

または追加:

public <Type> void add (Type value)
  {
    if (value instanceof Number){
        add_specific ((Number)value);
        str.append (String.format("%n"));
    }
  }
于 2013-10-08T15:19:11.457 に答える