javaarraylistincompatibletypeerrorunchecked-conversion

Java ArrayList type error/warning


While attempting to implement a custom data class I have run into the following problem. I'm simply trying to add items to an ArrayList but Java seems to have an issue with the types I'm using. I have tried multiple solutions to no avail. Below I have included the code from my custom datatype and from a simplified version of my code that throws the same errors. I have included the two solutions I tried and the error/warning each threw.

I am relatively new to code and especially to asking questions on StackOverflow so if I have forgotten anything or can clarify please let me know.

Custom Datatype:

  1 /**
  2 This file defines a transition function data type
  3 */
  4 
  5 import java.util.ArrayList;
  6 
  7 public class transition<X,Y,Z> {
  8         private ArrayList<Integer> current;
  9         private char scan;
 10         private ArrayList<Integer> future;
 11 
 12         //constructors
 13         public transition(int x, char y, int z) {
 14                 this.current = new ArrayList<Integer>();
 15                 this.current.add(x);
 16                 this.scan = y;
 17                 this.future = new ArrayList<Integer>();
 18                 this.future.add(z);
 19         }
 20 
 21         public transition(ArrayList<Integer> x, char y, ArrayList<Integer> z) {
 22                 this.current = new ArrayList<Integer>();
 23                 this.current = x;
 24                 this.scan = y;
 25                 this.future = new ArrayList<Integer>();
 26                 this.future = z;
 27         }
 28 
 29         //methods
 30         public ArrayList<Integer> getCurrent() {
 31                 return this.current;
 32         }
 33 
 34         public char getScan() {
 35                 return this.scan;
 36         }
 37 
 38         public ArrayList<Integer> getFuture() {
 39                 return this.future;
 40         }
 41 }

Simplified Code:

 1 /**
  2 Class designed to test out a bug encountered in my code
  3 */
  4 
  5 import java.util.ArrayList;
  6 
  7 public class test {
  8 
  9         public static void main(String[] args) {
 10 
 11                 //creating ArrayList and adding one transition to it
 12                 ArrayList<transition> list = new ArrayList<transition>();
 13                 transition trans = new transition(1, 'a', 2);
 14                 list.add(trans);
 15 
 16                 //creating list to add to
 17                 ArrayList<Integer> ints = new ArrayList<Integer>();
 18 
 19                 //testing loops over ArrayList and calls to trans
 20                 for(transition t : list) {
 21 
 22                         if(t.getCurrent().contains(1) && t.getScan() == 'a') {
 23 
 24                                                                         //Option 1
 25                                 ints.addAll(t.getFuture());             //t.java:24 warning: [unchecked] unchecked conversion
 26                                                                         //found    : java.util.ArrayList
 27                                                                         //required : java.util.Collection<? extends java.lang.Integer>
 28 
 29                                                                         //Option 2
 30                                 for(Integer j : t.getFuture()) {        //      t.java:26: incompatible types
 31                                         ints.add(j);                    //      found    : java.lang.Object
 32                                 }                                       //      required : java.lang.Integer
 33                         }
 34                 }
 35         }
 36 }

Solution

  • It's because transition is a generic class (it has 3 type parameters <X, Y, Z>).

    Since t is a raw transition (as opposed to a transition<String, Integer, Date> for example), all of the generic type information in transition is completely ignored for the variable t. (Yes, that really is how raw types work).

    So it's as if getFuture returns a mere ArrayList, rather than an ArrayList<Integer>.

    Just get rid of <X, Y, Z> (I see no reason why they're there anyway) and it should work.

    A simple demonstration of this problem is this:

    public class Main<T> {
    
        public static void main(String[] args) {
            int a = new Main().getList().get(0);       // Doesn't compile
        }
    
        List<Integer> getList() { return Arrays.asList(1, 2, 3); }
    }
    

    This doesn't compile, but if you delete <T>, it does.