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.

0

3 Answers 3

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.
Sign up to request clarification or add additional context in comments.

Comments

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.

4 Comments

it makes no sense to use the types and then pass Object .. you lose all control of types.
Can you share source of your quote?
@Pshemo added the link in Answer
This link should be part of your answer, not comment.
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();.

4 Comments

Queue<? extends Message> queue instead of Queue<? super Message> queue should also work here
It will not work. That won't let you add new objects, Refer stackoverflow.com/questions/4343202/…
not new Objects but objects of class extending Message like SMS objects
No, it will not. You can try it - I just tried and it wont let me add

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.