-2

I am trying to create an arraylist which can contain any type of object by using a generic with an unbounded wildcard.

ArrayList<?> params = new ArrayList<?>(); 

I do not understand why I receive the following error and I want to know where I am going wrong?

  required: class or interface without bounds
  found:    ?
coderboi27
  • 39
  • 2

3 Answers3

1

A simple approach to your problem is to use an ArrayList<Object>:

ArrayList<Object> params = new ArrayList<>(); 

The ? operator refers to all objects that are of unknown type, so using it to add objects of known type (e.g. String) will cause errors, as described here.

Anis R.
  • 6,656
  • 2
  • 15
  • 37
  • Don't use `Object` as generic parameter for collections. This is only marginally better than raw types. – Turing85 Jul 30 '19 at 19:07
  • @Turing85 how do you figure it is only marginally better than raw types? `Object` is no more or less valid than any other type: if you want to produce and consume elements of any type, `Object` is what you should use. – Andy Turner Jul 30 '19 at 19:12
  • @AndyTurner You use generics for type safety. In most cases, `Object` is not what you want and you end up casting anyway. I am aware that OPs approach does not leave much room for anything else, but it suggests that there is a flaw somewhere in the system. – Turing85 Jul 30 '19 at 19:13
  • @Turing85 but a `List` is as valid a choice as any, if that is what you require. It is not like a raw type, because you can't pass a `List` to a method expecting a `List`, whereas you can pass a raw `List`. – Andy Turner Jul 30 '19 at 19:37
  • @AndyTurner that is what I meant by "marginally better" =) – Turing85 Jul 30 '19 at 19:38
1

You simply aren't allowed to do this. It says this in JLS 15.9:

If TypeArguments is present immediately after new, or immediately before (, then it is a compile-time error if any of the type arguments are wildcards (§4.5.1).

A list instance never has a bounded type: a list is always a list with elements of a particular type.

It is only list variables which can be bounded, in order to store lists with elements of particular types within those bounds.

So, this would be fine:

ArrayList<?> params = new ArrayList<SomeType>(); 

or

ArrayList<?> params = new ArrayList<>();

That's not to say that you can't use bounds on the RHS at all:

new ArrayList<List<?>>()

would be fine, because List<?> isn't a wildcard (because syntactically wildcards always start with ?).

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

You can’t write new ArrayList<?> because there’s no such thing as an ArrayList<?>.

Every ArrayList has a specific type. When you write ArrayList<?> params, you are telling the compiler: “This variable will hold an ArrayList whose elements are a specific type, like String or Number, but as I write this line of code, I don’t know what that type will be.”

So you can refer to an ArrayList as having a type that is not known at compile time, but every existing ArrayList has an actual type, regardless of how variables refer to it. When code creates an ArrayList, that type has to be specified.

VGR
  • 40,506
  • 4
  • 48
  • 63