简体   繁体   中英

Java Generics List Compilation error

Why i get a compilation error in this line String s=data.get(idx);

Update: I get Type mismatch: cannot convert from E to String

    public class Parent<E> {
        ArrayList<E> data=new ArrayList<E>();

        public void add(E d){
            data.add(d);
        }
        public List<E> getData(){
            return data;
        }
    }

    public class Child<E> extends Parent<E>{

        public void appendData(E newItem){
            super.add(newItem);
        }
        public void displayData(int idx){
            List<E> data=this.getData();
            **String s=data.get(idx);**//I get compilation error in this line
            System.out.println(s);
        }

        public static void main(String[] args) {
            Child<String> c=new Child<String>();
            c.appendData("Data1");
            c.appendData("Data2");

            c.displayData(1);
        }
    }

Solution Updated Class:

public class Child<S> extends Parent<String>{

public void appendData(String newItem){
    super.add(newItem);
}
public void displayData(int idx){
    List<String> data=this.getData();
    String s=data.get(idx);
    System.out.println(s);
}

public static void main(String[] args) {
    Child c=new Child();
    c.appendData("Data1");
    c.appendData("Data2");

    c.displayData(1);
}
}

It shouldn't be something hard to understand:

In String s=data.get(idx); , data is in type of ArrayList<E> . Given you have no special restriction in E , it is possible to be any type that is NOT a String. Just think, what will happen if you are using a Child<Date> , for which the data is in fact an ArrayList<Date> , String s = data.get(i) simply doesn't make sense.

Hence, compiler complain to you that you cannot simply assume the result of data.get(index) to be a String.

The way to fix can be straight-forward. For example you can do whatever suggested in other people's answer. It may also be an issue of your design that, your Child should not bear type parameter and it should extends from Parent<String> . However it is more important that you understand why it doesn't work, so that you can choose the correct way to fix your problem.

干得好。

data.get(idx).toString();

That line should read:

E s = data.get(idx);

Then if you want to print it, you can do it like this:

System.out.println(s.toString());

This is not really related to generics . But to answer the question,

String s=data.get(idx);

should be replaced with

String s= String.valueOf( data.get(idx) );

If you are absolutely sure that data.get(idx) will never return null , you can also use:

String s= data.get(idx).toString() ;

Otherwise, you will receive NullPointerException s.

On a second read, you can also use

System.out.println( data.get(idx) ) ;

directly. Internally, this uses String.valueOf() so it's equally exception-safe.

The reason why you get the compilation error is because in the Child class, where you call data.get(idx) It doesn't know that it's going to be a String.

public void displayData(int idx) {
    List<E> data = this.getData();
    //String s=data.get(idx); //Doesn't compile because it won't know this is a String at runtime
    E s = data.get(idx); // To make it generic to the type in main, change the type to E
    System.out.println(s);
}

You can solve the problem either casting it to string or use string in your generic parameter

String s = data.get(idx);
ArrayList<String> data=new ArrayList<String>();

Reason you are getting this error because you are using Generic methods and type parameter So when you are assigning value from your generic list to a string you are getting error. Compiler does not know that your List actually contains string data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM