0

I have a simple question: is there a better way to create a collection that holds any-type objects. I have it like this:

Queue<Object> queue = new LinkedList<Object>();
        queue.add("First Element");
        queue.add(2);
        queue.add(true);

As I was reading about gerenic wildcards, I thought I could do something like this:

Queue<?> queue = new LinkedList<?>();

But I realise, that it is wrong, so I ask if my procedure is correct and how could I improve it using wildcards if possible.

Thanks for input everyone. Elaborating: I want to use this queue collection to store an unknown number of unknown objects, then perform an action with each of them in a loop. Hence, here I have a dilemma: what would be the best practice to create such a collection.

3 Answers3

1

This is correct :-

Queue<Object> queue = new LinkedList<Object>();

This will take any Object type as a input. But while using get() you can typecast it to the actual type.

The above is an example of Type Parameter Bound. According to the docs :- There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for. mentioned Here

For Reference on Diff Between a wildcard bound and a type parameter bound mentioned Here:-

What is the difference between a wildcard bound and a type parameter bound?

A wildcard can have only one bound, while a type parameter can have several bounds. A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter.

Wildcard bounds and type parameter bounds are often confused, because they are both called bounds and have in part similar syntax. […]

Syntax:

  type parameter bound     T extends Class & Interface1 & … & InterfaceN

  wildcard bound  
      upper bound          ? extends SuperType
      lower bound          ? super   SubType

A wildcard can have only one bound, either a lower or an upper bound. A list of wildcard bounds is not permitted.

A type parameter, in constrast, can have several bounds, but there is no such thing as a lower bound for a type parameter.

Ankit Nigam
  • 2,630
  • 3
  • 13
  • 21
1

What you have not seems OK, although it may be signal that instead of collection you could need separate class where you would store your data as fields.

Anyway you don't want wildcard <?>. It can be used only in reference, like

Queue<?> queue = ...

and it represents some specific type which you are not aware (or don't care, for now). You don't want to use it, since it can't allow you to add anything to collection because you could try placing Cat in collection of Dogs.

For example:

List<Dog> dogs = new List<Dog>();
List<?> someList = dogs; // it is OK, thanks to ? someList can be reference to List<Dog>
someList.add(new Cat()); // this would be wrong because Cat is not a Dog, 
                         // and probably shouldn't be placed in container 
                         // where you have lots of Dogs.
Pshemo
  • 113,402
  • 22
  • 170
  • 242
0

Typically, if you feel that you need to create a collection of type java.lang.Object, then, may be your design is flawed.

You may want to store objects that are of certain type - but they have variations. For example, you may queue the Message objects so that they get delivered by a delivery service. And, you may wish to queue both SMS and Email type of messages.

interface Message {
    ...
}

public static class SMS implements Message {
    ...
}

public static class Email implements Message {
    ...
}

In such cases, you would like your collection to make use of generics to enforce that all elements are of type Message.

You can do that by creating your collection as shown below

    Queue<? super Message> queue = new LinkedList<Message>();
    queue.add(new SMS());
    queue.add(new Email());

If you really really want a queue of type java.lang.Object, then, you can very well ditch the generics and use the type-unsafe collection - Queue queue = new LinkedList();.

Wand Maker
  • 17,377
  • 6
  • 43
  • 79