1

I want to create a generic method that accepts only an arraylist of integers. But the method is also accepting a raw type. How can I restrict it to accept only an arraylist of integers?

package generics;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class GenericBox<T> {
    public static void main(String[] args) {
        ArrayList l1 = new ArrayList();
        l1.add(1);
        l1.add("subbu");
        printListValues(l1);

        ArrayList<Integer> l2 = new ArrayList<>();
        l2.add(1);
        l2.add(2);
        printListValues(l2);
    }
    public static <T extends ArrayList<Integer>> void printListValues(T t){
        System.out.println(t);
    }
}

Thank you, Subbu.

Subbu
  • 217
  • 2
  • 11
  • 4
    What do you need the generic type for when it only accepts a single type `ArrayList`? – Thilo Sep 06 '19 at 07:45
  • `public static void printListValues(ArrayList list)` does not work? – Thilo Sep 06 '19 at 07:46
  • 2
    `public static void printListValues(ArrayList t)` ?? what do you mean generic that accepts only list of integer? if it accepts only one type, it's not generic – Nir Levy Sep 06 '19 at 07:46
  • @Thilo, I understand what you mean but I am a newbie and learning about generics and trying to understand bounded type parameters. Trying various examples and this one is one of them. – Subbu Sep 06 '19 at 07:48
  • 3
    I believe that `T`from class is not same as `T` declared for method.... – user85421 Sep 06 '19 at 07:48
  • Do you want to do `public static void printListValues(List t)`? –  Sep 06 '19 at 07:48
  • 3
    Well, generics allow you to be flexible about types of arguments and return values. If you don't need/want that flexibility, don't use generics. – Thilo Sep 06 '19 at 07:49
  • 1
    Speaking of flexibility, also think about `List` vs `ArrayList` for your parameter type. – Thilo Sep 06 '19 at 07:49
  • @Thilo, even if I change it to List the method still accepts raw lists (ArrayList or LinkedList). I would like to restrict it to only ArrayList or LinkedList. Looks like the answer from you below regarding backward compatibility answers that. Thank you. – Subbu Sep 06 '19 at 08:09

3 Answers3

1

But the method is also accepting a raw type

Are you saying that you want this call to be forbidden ?

printListValues(new ArrayList());  // raw type

The compiler will issue a warning about using raw types, but it will compile. You might be able to tell your compiler (examine its documentation or configuration GUI for how) to treat this as an error, and so forbid it.

The reason the compiler normally allows this is backwards-compatibility. Generics were added later in life (with Java 5) and are "opt-in". If the code uses generic types, they have to be correct, but you could forgo that altogether. The old "raw" code still continues to work (which is a strong selling point of Java).

Maybe there is a compiler option to turn warnings into errors, so you can prevent yourself from using raw types. But you cannot force others to do that.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Thilo
  • 257,207
  • 101
  • 511
  • 656
1

You simply cannot stop somebody passing in a raw-typed list.

For better or for worse (mostly the latter these days), raw types are a deeply-embedded part of the language. There is no getting away from them.

However, your method signature defines a contract:

public static void printListValues(ArrayList<Integer> t)

says "To work correctly, I need an ArrayList (or null). If that list is not null, I expect all of its elements to be Integer or null; and I expect the list to be able to consume instances of Integer or null without causing problems for the caller".

If you pass in anything else, the behaviour is undefined: caveat emptor. Most of the time, the compiler stops this happening, but if the type checks are disabled (by the use of raw types), you're on your own.

So, don't worry about people passing in a raw-typed list. If they ignore the contract of your method, and ignore the warnings from the compiler, they are getting everything they deserve.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

And you can use many Types and you can specify what kind of types it should accept

public class GenericBox<T> {
    public static void main(String[] args) {


        GenericProperties genericsPropertiesOnly=new GenericProperties();


        genericsPropertiesOnly.l2.add(1);
        genericsPropertiesOnly.l2.add(1);

        printListValues(genericsPropertiesOnly);
    }
//In here i am specifying to method should accept only Generic  from GenericProperties class

    public static <T extends GenericProperties> void printListValues(T t){ 
        System.out.println(t.l2);
    }

}

In here you can specify what kind of properties you are going to use

public class GenericProperties {

    private ArrayList<Integer> list;

    private ArrayList<String> listw;

    ArrayList<Integer> l2 = new ArrayList<>();


}


Dulaj Kulathunga
  • 1,248
  • 2
  • 9
  • 19