2015-12-09 1 views
19

以下の2つのコードスニペットの違いはわかりません。誰かが簡単な説明で私を助けることができますか?汎用スーパークラスとスーパークラスタイプの違い

まず、私はBaseEntityという名前のスーパークラスを拡張するクラスがたくさんあると言わなければならないので、次のスニペットの違い、利点、欠点は何ですか?あなたが復帰方法の制限を持っているあなたの最初のコードで

// 1 
public <T extends BaseEntity> T getName(T t) { 
    return t; 
} 

// 2 
public BaseEntity getName(BaseEntity t) { 
    return t; 
} 

答えて

24

最初のスニペットは、実際のタイプがTであるため、より柔軟です。あなたが書くことができる最初のケースで

class SubEntity extends BaseEntity {} 

SubEntity result = getName(new SubEntity()); 

しかし、あなたはキャストが必要になります後者の場合では:あなたは、サブクラスがあると

SubEntity result = (SubEntity)getName(new SubEntity()); 
1

1)BaseEntitysubclassesすべきであり、入力paramがBaseEntityの同じサブクラスでなければなりません。

2)2番目のコードでは、戻り値があり、メソッドのパラメータはsubclassesで、BaseEntityである必要があります。

+0

これは正しくありません。最初のコードスニペットでは、入力パラメータの型は 'return'値と同じ' BaseEntity'のサブクラスでなければなりません。これは、どんな種類のオブジェクトでもかまいません。2番目のスニペットでは、 'return'値と入力パラメータは' BaseEntity'のサブクラスでもあります。 – Daniel

7

主な違いとき2つの方法を使用することは、第2の場合における鋳造の必要性である。

のは、あなたが持っているとしましょう:第二の方法であなたが書く必要があろうが

MyEntity myEntity = ... 
MyEntity entity = getName(myEntity); 

:あなたはのようなものを持つことができる第1の方法に

public class MyEntity extends BaseEntity { 
} 

MyEntity entity = (MyEntity)getName(myEntity); 

これは、最初のメソッドで具体的な型を指定したためです。

4

これまでの回答では誰もこれを言及していないことに驚いていますが、2つのメソッド宣言の間には根本的な違いがあります(2番目のケースでのキャストが必要な理由です)。この違いは、あなたがここで提供している簡単なメソッドとは無関係ですが、単純にその引数を返すメソッドとは異なる何かを行うメソッドに違いをもたらす可能性があります。

あなたの最初のメソッド宣言は、戻り値の型が渡された引数と同じタイプである必要があります。だから、

public <T extends BaseEntity> T getName(T t) { 
    return new SubEntity(); // Where SubEntity extends BaseEntity 
} 

public BaseEntity getName(BaseEntity t) { 
    return new SubEntity(); // Where SubEntity extends BaseEntity 
} 

があっても、完全に合法であるのに対し、コンパイルに失敗しますこのメソッドに渡されたBaseEntityは、SubEntityとは全く異なる型です。

関連する問題