0

次のようなオブジェクトを返すメソッドがあります

public static Object login(DataManager dataManager, String userName, String password)       
    ArrayList<LoginCredentialsBean> loginCredentialsList = new ArrayList<LoginCredentialsBean>();       
    String authenticated = "false";     
    Connection connection = null;       
    try {           
        connection  = dataManager.getConnection();          
    } catch (Exception e) {         
         return ("Having problem in connectiong to databaste: " + e.getMessage());          
    }       
    if (connection != null) {           
         try {                                       
             ...                     
             try {                   
                 ResultSet rs = prepStatement.executeQuery();                   

                 try {                      
                     while (rs.next()) {
                         ...                             
                         loginCredentialsList.add(new LoginCredentialsBean(roleId, orgaCode, passwordExpiryDate, date, status, language));                                                          
                        authenticated = "true";                          
                     } //end of while()                                                  
                 } finally {                     
                     rs.close();                     
                 }                   
             } finally {
                 prepStatement.close();                  
             }                
             if (authenticated.equals("true")) {                     
                updateUserLogByInserting(connection, userName);                  
             }

         } catch(SQLException e) {               
             System.out.println("Could not login from dataabse:" + e.getMessage());              
         } finally {                 
             dataManager.putConnection(connection);                          
         }                  
    }       
    if (authenticated.equals("true")) {                 
        return loginCredentialsList;            
    } else {        
        return authenticated;           
    }       
} //end of login()

今、私はそれを次のようにテストしています

public static void main(String... args) {

    MoneyTreeServices moneyTreeServices = new MoneyTreeServices();

    Object result = moneyTreeServices.login("Admin", "cbas1234");       
    if (result instanceof ArrayList<?>) {

        System.out.println("ArrayList instance");           
    }       
    System.out.println(result);
}

それは私に次のような結果を返します

ArrayList instance
[pk.mazars.moneyTree.bean.LoginCredentialsBean@b7ec5d]

のような条件を使用していることを聞きたいですArrayList<?>。LoginCredentialsBeanオブジェクトを含むArrayListを確認するにはどうすればよいですか。私が使うときのように

if (result instanceof ArrayList<LoginCredentialsBean>) {

}

エラーが発生します

Can not perform instanceof check against parameterized type ArrayList<LoginCredentialsBean>. Use the form ArrayList<?>

ArrayListのinstanceを確認したいのですが、arraylistにLoginCredentialsBeanがありますか?

ありがとうございました。

4

6 に答える 6

1

パラメータ化された型情報はコンパイル時に消去instanceofされ、(ファンファーレ)実行時に解決されます-そのため、このエラーが発生します。

できることは、Listとの要素を反復処理することinstanceofです。

乾杯、

于 2012-10-23T08:27:03.990 に答える
1

簡単に言えば、あなたはできないということです。Integerジェネリックスは型消去を介して実装されます-それらは事実上コンパイル時の構文糖衣であり、に入れないようにしますList<String>

ただし、ランタイムオブジェクト自体は単なるraw型です。のインスタンスは、それが(というより、そのジェネリック型の変数に割り当てられていることを知りませArrayListん)。したがって、リフレクションを使用して問い合わせると、ジェネリック型の情報を取得できません。ArrayList<String>

私が考えることができる解決策には大きく分けて2つのタイプがあります。1つは、リストの内容を繰り返し処理し、それらの動的タイプを確認することです。LoginCredentialsBeanたとえば、最初の要素がである場合は、があると想定するのが妥当ですList<LoginCredentialsBean>。ただし、これは空のリストでは機能しません。これは問題になる可能性があり、誤検知を引き起こす可能性があります(たとえば、最初の要素としてList<Object> allParametersが発生する可能性がありLoginCredentialsBeanます...)

もう1つは、メタデータオブジェクトを明示的に渡すことです。この場合Object、メソッドから、loginオブジェクトのタイプを説明するトークンとともにを返します。これは単純な列挙型定数である可能性があります。または、極端に言えば、トークンを一般的に型指定して、コンパイラーがこれを返されるものの型と照合し、トークンが型が正しいことを確認できるようにすることができます。

しかし、いずれにせよ、instanceof少なすぎる(情報)、遅すぎる。


気をつけてください、あなたのlogin方法は...奇妙に見えます。Objectそれはただ怠惰で、ここであなたを助ける静的型システムを完全に破壊しているので、私はそれがまったく返すべきではないと思います。List<LoginCredentialsBean>むしろ、指定されたログインに関連する資格情報を含むを返すだけでよいと思います。

戻るには3つの異なるパスがあります。1つ目は、データベースへの接続時に例外が発生した場合です。この場合、例外をスローする必要があります。エラーの詳細を含む文字列を返すことは、非常に非典型的で紛らわしいことです。例外的な条件は、として処理する必要がありExceptionます。

他の2つの状況は、最終的な結果を検索できる状況です。ログインに失敗した場合は、空のリストを返すだけです(つまり、このユーザー名/パスワードには資格情報がまったくありません)。ログインが成功すると、入力されたリストが返されます。

ログインの失敗と成功したログイン(資格情報なし)を強く区別できるようにしたい場合は、代わりに次のような複合オブジェクトを返します。

class LoginStatus {
    final boolean authenticated;
    final List<LoginCredentialsBean> credentials;
}

いずれにせよ、呼び出し元は何が返されているかを正確に把握しており、呼び出しinstanceofや型キャストを行わなくても、メソッドを適切に呼び出すことができます。

于 2012-10-23T08:27:42.493 に答える
0

あなたはそれを二度チェックしなければなりません。

if (result instanceof ArrayList<?>) {
 System.out.println("ArrayList instance");
 //cast
 ArrayList<LoginCredentialsBean> list = (ArrayList<LoginCredentialsBean>) result;

  ///..check if list contains LoginCredentialsBean
 for(int i=0; i<list.size(); i++){
  if(list.get(i) instanceof LoginCredentialsBean){
   System.out.println("LoginCredentialsBean instance");
  }  
 }
}     
于 2012-10-23T08:27:52.743 に答える
0

「LoginCredentialsBean を含む ArrayList」のようなものはありません。ArrayList には常にオブジェクトが含まれています。

リストを反復処理して、各オブジェクトをチェックする必要があります。

for (Object o: result) {
     if (!(o instanceof LoginCredentialsBean)) {
           //Fail
     }
}
于 2012-10-23T08:28:55.533 に答える
0

を使用しcontains(Object o)て、ArrayList にオブジェクトが含まれているかどうかを確認できます。を使用しinstanceof Listて、指定されたオブジェクトがリストかどうかを確認します。実行時の型消去のため、リストのジェネリック型は利用できません

于 2012-10-23T08:29:01.107 に答える
0

loginメソッドが型を返す場合、Object試した方法でこれを確認する方法はありません。型消去のため、型パラメーターはコンパイル時にのみ存在します。返されたオブジェクトがListまたはCollectionまたは ただのであるかどうかを確認しIterable、それを繰り返し処理して、 のインスタンスである場合はすべてのアイテムを確認する必要がありますLoginCredentialsBean

ただし、コードは悪い設計の例です。Stringまたはリストを返すメソッドは間違っています。それを正しくするには:

  • 戻させるList<LoginCredentialsBean>
  • 認証が失敗した場合にチェック例外をスローする

public static List<LoginCredentialsBean> login(DataManager dataManager, String userName, String password) throws AuthenticationException {...}

注:または文字列booleanの代わりに論理データを保持するために使用します。"true""false"

于 2012-10-23T08:32:04.660 に答える