This week's book giveaways are in the Refactoring and Agile forums.
We're giving away four copies each of Re-engineering Legacy Software and Docker in Action and have the authors on-line!
See this thread and this one for details.
Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Generics Problem

 
Nirodha Abeywardana
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
this is compiling with warnings. how this can be happan pls explain.
List myList = new ArrayList(); is same as List<Object> myList = new ArrayList<Object>();
method argument is type List<String>, but Object can not cast to String type implecitly

public class GenericsTest {
public static void main(String[] args) {
List myList = new ArrayList();
myList.add("Fred");
myList.add("Test0000");
myList.add("Test1111");
GenericsTest gt =new GenericsTest();
gt.takeListOfStrings(myList1);
}

void takeListOfStrings(List<String> strings) {
strings.add("foo");
}
}
 
Satish Kota
Ranch Hand
Posts: 88
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The java compiler will check for any compatibility errors when you assign a generic collection to another generic collection.
Java compiler won't check for any compatibility errors instead warns you:
1. When you assign a non generic collection to a generic collection or 2. When you assign a generic collection to a non-generic collection

The reason for 2nd case is because sun wants to provide backward compatibility. I am not sure why the 1st case is allowed. Hope some ranchers throw some light into this.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First, this will not compile at all:
1. missing import of java.util.*; and 2. myList1 is undefined.

Second, consider this:


In Java 5.0 this is legacy style code - Sun wants you to use type safe generics in new code. Now myList could be a list of Strings, Integers, Fruit, or any objects of any class. If it is a List of Strings then it is OK to add a String to it. But if is not a List of Strings then you may have corrupted your list. So later, if you did String s = (String)myList.get(0); you would get a ClassCastException. The compiler is informing you of this possibility by emiting the "unchecked" warning. At the compile stage the compiler does not need to know what you have actually assigned to myList.

It is a similar situation when the method takeListOfStrings is called. The method expects a List<String> as an argument but myList could possibly be not a list of strings - so you risk corrupting your input list if you allow takeListOfStrings to put a string into it. Once again the compiler is warning you that you could be facing a problem later on when you take something out of myList.
 
Wes Misenheimer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, what he needs to do, after correcting the compile errors,
is to change the following:

List<String> myList = new ArrayList<String>();

Am I correct?
 
Manju Devarla
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
import java.util.*;

public class Test {
public static void main(String[] args) {
List myList1 = new ArrayList(); //Line 1
myList1.add("Fred");
myList1.add("Test0000");
myList1.add("Test1111");

Test gt =new Test();
gt.takeListOfStrings(myList1);
System.out.println(myList1);
}

void takeListOfStrings(List<String> strings) {
strings.add("foo");
}
}

Above program compiles and runs instead of List<String> myList1 = new ArrayList<String>();

And below two are same

List myList1 = new ArrayList(); and
List<Object> myList1 = new ArrayList<Object>();


import java.util.*;


class Test {

public static void main(String s[]) {

//ArrayList<Object> obj=new ArrayList<Object>(); //Both declaration works

ArrayList obj=new ArrayList();

o.add(new Object());
}
public static void add(Object o) { //System.out.println(o); }
}
 
Wes Misenheimer
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe this is what you are trying to do:

It compiles without error or warning.

The only changes are labelled "Line 1", "Line 2", and "Line 3"
(other than to correct compile errors mentioned above).

Lines 2 and 3 are just so we can see some output - makes me feel better.

**Line 1 is the important part. It insures that only strings will make it into this List, which is the objective, isn't it? Try putting something else like

myList.add("Test1111");

right after the others calls to add().

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic