Instanceof with List in JAVA

Asked

Viewed 536 times

-2

I have declared a method that receives a List of the kind Object. But when I try to recognize him as instanceof it gives error. I have tried to do a casting but still giving error and could not identify where is the problem in my code. Someone can help?

public static void insertLog(List<Object> list) throws IOException{

    if (list instanceof List<Transaction>){
        for(Transaction transaction : list){
            insertLog(transaction.toString());
        }
    }

    else if (list instanceof List<Data>){
        for(Data data : list){
            insertLog(data.toString());
        }
    }

}
public static void insertLog(CashTransactionRequest request) throws IOException{
    insertLog(request.getClient().getCustomer());
    insertLog(request.getClient().getTeller());
    insertLog(request.getClient().getTellerName());

    insertLog(request.getDevice().getCountryId());
    insertLog(request.getDevice().getDelegation());
    insertLog(request.getDevice().getDeviceId());
    insertLog(request.getDevice().getDeviceName());
    insertLog(request.getDevice().getDeviceType());
    insertLog(request.getDevice().getTimeZone());

    insertLog(request.getAdditionalData().getData());

    insertLog(request.getTransaction());
}
  • You can tell what mistake it is ?

  • 1

    In Java, the Generics reference is not stored. So, Java cannot tell the difference between List<Banana> of List<Laranja>. So you might end up mixing bananas with oranges if you’re not careful

  • 1

    Can add doubt code?

  • 1

    Also, prefer to publish code to the image. I would even try to make a correction to what you wrote, but as it is in image there is no copy and paste. Even, the fact of having used images and not codes may be the reason for the negative vote

  • 1

    If you’re gonna use the toString there’s no point in casting

  • Check this out: https://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Show 1 more comment

3 answers

4


You can check for the item instead of the list:

public static void insertLog(List list) {
  for (Object item : list) {
    if (item instanceof Transaction) {
      insertLog((Transaction) item);
    } else if (item instanceof Data) {
      insertLog((Data) item);
    }
  }
}

I noticed that in your example you use String. To make the toString there is no need to perform conversion, so it is not necessary to perform the verification either.

4

List<Transaction> is not a List<Object>. List<Data> is also not a List<Object>. The reason is that in a List<Object> you can add any object, while in a List<Transaction> you can only add objects of the type Transaction. In the List<Data> you can only add objects Data.

Every object has a method getClass() which returns another object (of type Class) representing the object class. If you do this:

List<Transaction> lista1 = new ArrayList<Transaction>();
System.out.println(lista1.getClass().getName());
List<Data> lista2 = new ArrayList<Data>();
System.out.println(lista2.getClass().getName());
System.out.println(lista1.getClass() == lista2.getClass());

It will print:

java.util.ArrayList
java.util.ArrayList
true

That is, both lists have the same type. The generic does not matter.

The operator instanceof look at the class of getClass(). The generic is lost in this case. That is, no use doing instanceof List<Transaction> or instanceof List<Data>, for the instanceof does not see generics and only sees List.

Why don’t you just do it?

public static void insertLog(List<Object> list) throws IOException {
    for (Object item : list) {
        insertLog(item.toString());
    }
}

2

In the reply by @Sorack, it provides two alternatives on how to treat the issue. A Reply from @Victorstafusa provides more details and offers the solution via toString() mentioned by @Sorack. I’m going to propose something here a little more functional.

PS: a little more focused because it could be very well treated in a more idiomatic way, but as I am far from a computer I can not validate

Suppose you know how to insert into log an information E any. It may be Logger.insertData for objects of the type Data and Logger.insertTransaction for objects of the type Transaction.

public static <E> void insertLog(List<E> list, Consumer<E> logAtom) throws IOException {
  list.forEach(logAtom::accept);
}


// exemplo de chamada
public static void insertLog() {
  List<Transaction> transacoes = getTransacoes();
  insertLog(transacoes, Logger::insertTransaction);

  List<Data> datas = getDatas();
  insertLog(datas, Logger::insertData);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.