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 Integer into a List<String>.
The runtime objects themselves, however, are just the raw types. An instance of ArrayList doesn't know that it's an ArrayList<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 a List<LoginCredentialsBean>. This won't work for empty lists though, which could be a problem, and can potentially give false positives (e.g. a List<Object> allParameters might happen to have a LoginCredentialsBean as its first element...)
The other is to explicitly pass metadata objects around - so in this case you'd return the Object from the login method, 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, instanceof is too little (information), too late.
Mind you, your login method looks... odd. I don't think it should return an Object at 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 a List<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:
class LoginStatus {
final boolean authenticated;
final List<LoginCredentialsBean> credentials;
}
Either way, the caller knows exactly what they're getting back, and can call methods on it appropriately without having to call instanceof and typecast.
Parameterized type info is erased at compile time and instanceof is resolved at (fanfare) runtime - that is why you get that error.
What you could do is iterate over the elements in the List and instanceof them.
Cheers,
You have to check it twice.
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");
}
}
}
There is no such thing like "ArrayList that contain LoginCredentialsBean"
ArrayList contains Objects, all the time.
you must iterate over the list and check each object:
for (Object o: result) {
if (!(o instanceof LoginCredentialsBean)) {
//Fail
}
}
you can use the contains(Object o) to check whether the ArrayList contains your object. With the instanceof List to check whether the given object is a List. Because of type erasure at runtime the generic type of the List wont be available
If your login method returns an Object type there is no way to check this the way you try.
Type parameters exist only on compile-time due to type erasure. You need to check if retuned object is a List or Collection or just Iterable, then iterate throuh it and check every item, if it is a instance of LoginCredentialsBean.
However, your code is an example of bad design. A method that returns a String or a list is just wrong. To make it right:
make it return List<LoginCredentialsBean>
throw a checked exception if authentication fails
public static List<LoginCredentialsBean> login(DataManager dataManager, String userName, String password) throws AuthenticationException {...}
Note: Use boolean to keep logical data instead of "true" or "false" strings.
Related
Is method chaining good?
I am not against functional programming that uses method chaining a lot, but against a herd mentality where people mindlessly run behind something that is new.
The example, if I am processing a list of items using stream programming and need to find out the exact row that resulted into throwing NullPointerException.
private void test() {
List<User> aList = new ArrayList<>();
// fill aList with some data
aList.stream().forEach(x -> doSomethingMeaningFul(x.getAddress()));
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
So in the example above if any object in list is null, it will lead to NullPointerException while calling x.getAddress() and come out, without giving us a hook to identify a User record which has this problem.
I may be missing something that offers this feature in stream programming, any help is appreciated.
Edit 1:
NPE is just an example, but there are several other RuntimeExceptions that could occur. Writing filter would essentially mean checking for every RTE condition based on the operation I am performing. And checking for every operation will become a pain.
To give a better idea about what I mean following is the snippet using older methods; I couldn't find any equivalent with streams / functional programming methods.
List<User> aList = new ArrayList<>();
// Fill list with some data
int counter = 0;
User u = null;
try {
for (;counter < aList.size(); counter++) {
u = aList.get(counter);
u.doSomething();
int result = u.getX() / u.getY();
}
} catch(Exception e) {
System.out.println("Error processing at index:" + counter + " with User record:" + u);
System.out.println("Exception:" + e);
}
This will be a boon during the maintenance phase(longest phase) pointing exact data related issues which are difficult to reproduce.
**Benefits:**
- Find exact index causing issue, pointing to data
- Any RTE is recorded and analyzed against the user record
- Smaller stacktrace to look at
Is method chaining good?
As so often, the simple answer is: it depends.
When you
know what you are doing
are be very sure that elements will never be null, thus the chance for an NPE in such a construct is (close to) 0
and the chaining of calls leads to improved readability
then sure, chain calls.
If any of the above criteria isn't clearly fulfilled, then consider not doing that.
In any case, it might be helpful to distribute your method calls on new lines. Tools like IntelliJ actually give you advanced type information for each line, when you do that (well, not always, see my own question ;)
From a different perspective: to the compiler, it doesn't matter much if you chain call. That really only matters to humans. Either for readability, or during debugging.
There are a few aspects to this.
1) Nulls
It's best to avoid the problem of checking for nulls, by never assigning null. This applies whether you're doing functional programming or not. Unfortunately a lot of library code does expose the possibility of a null return value, but try to limit exposure to this by handling it in one place.
Regardless of whether you're doing FP or not, you'll find you get a lot less frustrated if you never have to write null checks when calling your own methods, because your own methods can never return null.
An alternative to variables that might be null, is to use Java 8's Optional class.
Instead of:
public String myMethod(int i) {
if(i>0) {
return "Hello";
} else {
return null;
}
}
Do:
public Optional<String> myMethod(int i) {
if(i>0) {
return Optional.of("Hello");
} else {
return Optional.empty();
}
Look at Optional Javadoc to see how this forces the caller to think about the possibility of an Optional.empty() response.
As a bridge between the worlds of "null represents absent" and "Optional.empty() represents absent", you can use Optional.ofNullable(val) which returns Empty when val == null. But do bear in mind that Optional.empty() and Optional.of(null) are different values.
2) Exceptions
It's true that throwing an exception in a stream handler doesn't work very well. Exceptions aren't a very FP-friendly mechanism. The FP-friendly alternative is Either -- which isn't a standard part of Java but is easy to write yourself or find in third party libraries: Is there an equivalent of Scala's Either in Java 8?
public Either<Exception, Result> meaningfulMethod(Value val) {
try {
return Either.right(methodThatMightThrow(val));
} catch (Exception e) {
return Either.left(e);
}
}
... then:
List<Either<Exception, Result>> results = listOfValues.stream().map(meaningfulMethod).collect(Collectors.toList());
3) Indexes
You want to know the index of the stream element, when you're using a stream made from a List? See Is there a concise way to iterate over a stream with indices in Java 8?
In your test() function you are creating an emptylist List<User> aList = new ArrayList<>();
And doing for each on it. First add some element to
aList
If you want to handle null values you can add .filter(x-> x != null) this before foreach it will filter out all null value
Below is code
private void test() {
List<User> aList = new ArrayList<>();
aList.stream().filter(x-> x != null).forEach(x -> doSomethingMeaningFul(x.getAddress()));
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
You can write a black of code in streams. And you can find out the list item which might result in NullPointerException. I hope this code might help
private void test() {
List<User> aList = new ArrayList<>();
aList.stream().forEach(x -> {
if(x.getAddress() != null)
return doSomethingMeaningFul(x.getAddress())
else
system.out.println(x+ "doesn't have address");
});
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
If you want you can throw NullPointerException or custom excption like AddressNotFoundException in the else part
I want to know the best way to check variable type at runtime.
public Iterator<?> read(String entityName, String propertyName, Object propertyValue) {
String query = "select * from " + entityName + " where " + propertyName + "=";
try {
int value = Integer.parseInt((String)propertyValue);
query=query+value;
} catch (NumberFormatException e) {
// failed
}
try {
String value = (String)propertyValue;
query=query+"'"+value+"'";
} catch (ClassCastException e) {
// failed
}
try {
float value = Float.parseFloat((String)propertyValue);
query=query+value;
} catch (NumberFormatException e) {
// failed
}
//Creating JDBC connection and execute query
Iterator<Element> result=queryConn.execute();
return result;
}
I need to check the variable type is int, float or String during runtime. Is there any other best way to do this?
Or Do I need to write seperate method for each variable type?
try this code :
if(floatVariable instanceof Float){}
if(intVariable instanceof Integer){}
if(stringVariable instanceof String){}
There are many ways to handle this scenario.
Use function overloading for different data types
Use instanceof operator to determine data type
Try to cast property value in any numeric data type, if successfully castes then ignore single quotes otherwise apply single quotes
since you are getting object as input you can always check using instanceof keyword.And instead of using primitives try using classes like(Integer.class).And one more thing is you should use PreparedStatement always.Your code is prone to SqlInjection.
Is there any other best way to do this?
I would recommend that you name the columns you want to select in your actual query. If you take this approach, you can parse each column as the appropriate type without worrying about type casting issues. If, for example, the first column selected were an integer type, then you would just call Integer.parseInt() without worrying about having the wrong type.
And here is an argument why using SELECT * is an anti-pattern:
If you use SELECT * as your query, then we don't even know how many columns are being returned. To even take a guess at that, we would have to analyze how many columns your code seems to expect. But, what would happen if someone were to change the schema, thereby possibly changing the order in which the RDBMS returns columns? Then your entire application logic might have to change.
I have 3 fields (name, password, email). I want to check if they are valid or not. I wrote the following
public boolean isValidInput() {
if(name.isValid()){
return false;
}
if(password.isInValid()){
return false;
}
if(email.isInValid()){
return false;
}
return true;
}
so this will give me a single invalid. But what to do if I want to show the invalids all at the same time?
There are multiple ways you can handle this. But each of them need a change in the caller to handle these cases.
Create a custom exception which accepts a list of messages. Every time a validation failed add the error to the list, at the end of isValidInput() if the list is not empty then throw an exception with the list of errors.
Return the list of errors from above, instead of throwing exception.
Return a list of boolean variable and each index in the list will represent the status of a validation (name, email, etc)
Have an Enum of all fields that are present. Return a list of enum that failed. Empty list indicates that no error has occurred.
There are still a lot of other ways to handle this. It all depends on what suits you the best.
I would say, try some of them and see how it goes.
You could simply return an integer from the function like this
public int isValidInput() {
if(name.isValid()){
return 1;
}
if(password.isInValid()){
return 2;
}
if(email.isInValid()){
return 3;
}
return 0;
}
and then check the integer to find out which one failed!
It would be better of course to define static final ints with the names of the errors to make the code more readable and robust.
I've been receiving ClassCastException in my code. Objective initially was to convert Set to List since the refreshDetailVOTable method will only get Set. The problem could have been in converting Set to List. refreshDetailVOTable might took the wrong List that's why I'm receiving ClassCastException. Any thoughts on this?
public List deleteChildPromotionComponentDetails(ClientContext context, List detailIRsToDelete,
String emergencyAccessPermission) throws RetekBusinessException {
List exclusionList = null;
RpmEvent deleteEvent = buildPromotionComponentDetailsDeleteEvent(emergencyAccessPermission);
deleteEvent.setTransitionNotificationExceptionFlag(true);
Set detailBOsToDelete = new HashSet();
for (Iterator iDetails = detailIRsToDelete.iterator(); iDetails.hasNext();) {
IdentifiableReference detailIR = (IdentifiableReference) iDetails.next();
PromotionComponentDetail promotionComponentDetail = (PromotionComponentDetail) getService()
.readForUpdate(detailIR);
Set exclusionSet = promotionComponentDetail.getExceptionsAndExclusions();
exclusionList = new ArrayList (exclusionSet);
for(Iterator exclusion = exclusionSet.iterator(); exclusion.hasNext();){
PromotionComponentDetail exclusionDel = (PromotionComponentDetail) exclusion.next();
exclusionDel.accept(deleteEvent);
detailBOsToDelete.add(promotionComponentDetail);
}
}
return exclusionList;
}
public void deleteChildDetails(final List parentComponentDetails)
{
List list = null;
try {
list = getCmlPromotionComponentDetailAppService().deleteChildPromotionComponentDetails(
ClientContext.getInstance(), parentComponentDetails,
emergencyPermission.getName());
} catch (RetekBusinessException e) {
e.printStackTrace();
}
refreshDetailVOTable(list);
}
Take a look at the generics tutorial here:
http://docs.oracle.com/javase/tutorial/java/generics/
You're doing pretty simple stuff, so you only need to look at the first part. You probably don't need to dive into wildcards.
A guess as to what's happening: your method is receiving a parameter List detailIRsToDelete from which you get an iterator and iterate over the elements like so:
for (Iterator iDetails = detailIRsToDelete.iterator(); iDetails.hasNext();) {
IdentifiableReference detailIR = (IdentifiableReference) iDetails.next();
...
}
If whoever calls you had accidentally put something other than an IdentifiableReference into detailIRsToDelete, you'd get a ClassCastException in the assignment statement within the loop. If instead the list parameter were declared
List<IdentifiableReference> detailIRsToDelete
the act of putting things into this list would be checked by the compiler, and the error would occur at the point where the erroneous object was added, at compile time, instead of later at runtime, as you're experiencing.
I have created a method that uses an iterator that iterates through a map and for each pair it evaluates a statement with many OR conditions. If the condition is true, it adds the object of the pair (a Notification object) in a list (anomalies). However, at compilation time, the compiler gives a NullPointerException exception at this method. Based on my investigation, it seems that there is a problem in the if statement, but I can't see why. Can anyone give me an help in this? Thanks!
public List<Notification> getAnomalies(NotificationSearchCriteria notificationSearchCriteria) {
Map<String,Notification> messageList = new HashMap<String,Notification>();
List<Notification> anomalies = new ArrayList<Notification>();
Iterator iterator = messageList.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry pairs = (Map.Entry)iterator.next();
Notification message = (Notification) pairs.getValue();
if(message.getDescription().equals(notificationSearchCriteria.getDescription())||message.getSubjectName().equals(notificationSearchCriteria.getSubjectName())||message.getNotificationSubject().toString().equals(notificationSearchCriteria.getNotificationSubject().toString())||message.getNotificationType().toString().equals(notificationSearchCriteria.getNotificationType().toString())){
anomalies.add(message);
}
}
}
return anomalies;
}
This is most likely caused by one of the methods on message returning null. For example, if message.getDescription() returns null, then message.getDescription().equals(<something>) will throw a NullPointerException, since you can't call additional methods on a null object.
There are several ways to fix this. First off, I recommend inspecting your objects to see which can return a null value and add the appropriate handling code.
More generally, I always recommend calling equals on the variable you know not to be null to avoid these problems. For example
if ("accept".equals(command)) {
// do something
}
is generally better than
if (command.equals("accept")) {
// do something
}
because the second might through an NPE, while the first never will.
I would refactor the message-matching code into the NotificationSearchCriteria class. The if would end up being "if (notificationSearchCriteria.matches(message))". From the names, I am guessing that is NotificationSearchCriteria's only usage; in that sense, it would not increase coupling.
The check-for-null would be performed during NotificationSearchCriteria construction; which would ensure that all fields were non-null. In the matching code, within that class, things would look like:
boolean matches(Notification message) {
if (description.equals(message.getDescription()) || // LHS guaranteed non-null
foo.equals(message.getFoo()) ||
bar.equals(message.getBar()) || // ...
) { return true; }
}
The best way to code is to do null check.
Ideally I would have code like this :
while (iterator.hasNext()) {
Map.Entry pairs = (Map.Entry)iterator.next();
Notification message = (Notification) pairs.getValue();
if(null!=message && null!=message.getDescription() &&
null!=notificationSearchCriteria.getDescription() )
{
//Do your comparioson
}else{
//Handle the NullPointerException error the way you want
}
}