I have a method from which i am returning object like
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()
Now i am testing it like
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);
}
It returns me result like
ArrayList instance
[pk.mazars.moneyTree.bean.LoginCredentialsBean@b7ec5d]
I want to ask i am using condition like ArrayList<?>. How can i check that ArrayList that contain LoginCredentialsBean object. Like when i use
if (result instanceof ArrayList<LoginCredentialsBean>) {
}
i get error that
Can not perform instanceof check against parameterized type ArrayList<LoginCredentialsBean>. Use the form ArrayList<?>
I want to check instanceof ArrayList and arraylist has LoginCredentialsBean ?
Thank you.
The short answer is that you can’t. Generics are implemented via type erasure – they’re effectively a compile-time syntactic sugar to ensure you don’t put an
Integerinto aList<String>.The runtime objects themselves, however, are just the raw types. An instance of
ArrayListdoesn’t know that it’s anArrayList<String>(or rather, that it was assigned to a variable with that generic type). So when you interrogate it with reflection, you cannot get any generic type info.There are two broad types of solution I can think of. One is to iterate over the list contents and check their dynamic type – if the first element is a
LoginCredentialsBean, for example, then it’s reasonable to assume that you have aList<LoginCredentialsBean>. This won’t work for empty lists though, which could be a problem, and can potentially give false positives (e.g. aList<Object> allParametersmight happen to have aLoginCredentialsBeanas its first element…)The other is to explicitly pass metadata objects around – so in this case you’d return the
Objectfrom theloginmethod, along with a token which describes what type of object it is. This could be a simple enum constant; or going to the other extreme you could make the tokens generically typed, such that the compiler can check this against the type of what you’re returning and ensure that the tokens are type-correct.But in any case,
instanceofis too little (information), too late.Mind you, your
loginmethod looks… odd. I don’t think it should return anObjectat all, as that’s just lazy and completely subverting the static type system which would help you here. Rather, I think it should just return aList<LoginCredentialsBean>containing the credentials that pertain to the given login.You have three different paths where you return. The first is if an exception is encountered when connecting to the database – in which case you should throw an exception! Returning a string with the error details is very atypical and confusing – an exceptional condition should be handled as an
Exception, that’s what they’re for.The other two situations are ones where you’re able to look up definitive results. For the failed login case, I would just return an empty list (i.e. this username/password has no credentials whatsoever), while returning the populated list during a successful login.
If you strongly want to be able to distinguish between a login failure, and a successful login (with no credentials), then perhaps return a compound object instead, such as:
Either way, the caller knows exactly what they’re getting back, and can call methods on it appropriately without having to call
instanceofand typecast.