3

たとえば、次のようにObject「ふりをする」ことがありますString

Object o = new String("dsadsa");

そのオブジェクトの文字列関数を使用する場合は、まず次のように文字列に変換する必要があります。

((String)o).indexOf("sad");

非常に多くの括弧があると、これは本当に面倒で読めなくなります! 特に、それが IF ステートメントまたは関数に含まれる必要がある場合は!

if (((String)o).equals("dsadsa")) {}

このような状況を回避する最善の方法は何ですか?

4

10 に答える 10

9

解決策は、メソッドのプロトタイプなどで、オブジェクトが正確なクラスであることを確認することです。

これは実行時エラーの回避にも役立つため、ベスト プラクティスです。

これは、パラメーター化されたクラス (ジェネリック) を使用するとますます簡単になります。

別の言い方をすると、コードに多くのキャストがある場合は、おそらく設計上の問題があります。しかし、解決策を提案するには、さらにコードが必要です。

于 2012-08-22T15:28:47.563 に答える
8

オブジェクトを 1 行でキャストします。

キャストされたオブジェクトを別の行で使用します。

于 2012-08-22T15:28:11.407 に答える
7

実際には、ジェネリックを正しく使用すると、コードで見たほとんどのキャストが取り除かれます。

ただし、何らかの理由でそれができない場合 (古い Java バージョン、レガシー ライブラリ) は、できるだけ早い機会にキャストを行うローカル変数を作成します。

特殊なケースは、オブジェクトをインターフェイス型からその実装にキャストする場合です。これはほとんどの場合間違っており、インターフェイスの設計が不適切であることを意味します。

于 2012-08-22T15:28:48.403 に答える
5

標準的な方法は、オブジェクトをより狭い型の変数 (この場合は変数) に常にキャプチャし、String str後でそれを使用することです。

3 番目の例では、ダウンキャストする必要がないことに注意してください:o.equals(o2)も機能します。

Java Generics を勉強することに決めた場合、すぐにがっかりするかもしれません。多くの場合、冗長性がダウンキャストから型宣言に移行するだけです。Generics に書き直すと、多くのコード スニペットは同じくらい長くなり、さらに長くなるものもあります。

于 2012-08-22T15:30:21.747 に答える
2

Stringのふりをしていると言うつもりだったと思いますObject

あなたのハンドルは Object 型ですが、そうである必要はありません。

  1. オブジェクト型を使用している場合は、メソッドが取得するパラメーターであるため、実際に文字列が必要な場合は、パラメーターの型を文字列に変更することを検討してください。
  2. これがコレクションからのものである場合は、コレクションをジェネリックを使用するように変更して、コレクションを文字列型として定義できるようにすることを検討してください。
  3. なんらかの理由で入ってくるオブジェクトの型を変更できない場合は、それが実際に文字列であることを確認し、文字列型の別の変数に一度キャストします。

3 番目のオプションのコードは次のようになります。

String s;
if (o instanceof String) {
    s = (String) o;
} else {
    s = null;
    throw new IllegalArgumentException();
    // Or take some corrective action.
}
于 2012-08-22T15:37:54.887 に答える
1

私はそれをお勧めしませんが、あなたはこれを行うことができます:

String.class.cast(o).indexOf("sad");
于 2012-08-22T16:28:35.657 に答える
1

私はそうは思わない。スーパークラスをサブクラスに明示的にキャストする必要があります。

String str;

if(o instanceOf String){
   str =(String)o;
   str.indexOf("sad");
   ...
}
于 2012-08-22T15:31:50.730 に答える
1

you can do some dangerous things taking advantage of generics like

public static <T> T cast(Object o){
    return (T) o;
}

This allows you do do things like

Object o="";
String s = cast(o);

It is really hacky but you could do something like

public static String s(Object o){
    return (String) o;
}

and then

    Object o = "";
    s(o).indexOf("sad");
于 2012-08-22T15:36:51.213 に答える
0

"dsadsa".equals(someString)それがどのように行われるかです - 効果的にNPEの可能性を取り除き、someString実際にオブジェクトとして宣言されていても仮想呼び出しがないようにします。

また、呼び出すためにキャストする必要はありませんequals()

ジェネリックを使用できることは別として、それらは過度に冗長な構文を持っています。特に次のようなものに関しては<T extends Foo &Bar> T selectFooBared(List<java.lang.ref.Reference<T>> list, Comparator<? super T> c);

于 2012-08-25T12:24:23.810 に答える
0

コンパイル時の型チェックが必要ないようです。次に、Groovy などのスクリプト言語を使用します。Groovy も JVM 上で実行されますが、静的型付けは必要ありません。

于 2012-08-22T23:18:20.770 に答える