Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simple generic list in java

Tags:

java

generics

Why are java generics so tricky? I thought I finally understood, but eclipse gives me an error at the line in somOtherMethod below using either of the getOuterList methods below.

protected List<?> getOuterList() {
  // blah blah
}

protected List<? extends Object> getOuterList() {
  // blah blah
}

protected void someOtherMethod() {
  ...
  getOuterList().add((MyObject)myObject);  //compile error
  ...
}

UPDATE: ok - so I understand the error now. It was lack of understanding on my part of what List<?> or List<? extends SomeObject> really means. In the former case, I thought it meant a list that could contain anything. In the latter case, I assumed it was a list of a bunch of objects that extend SomeObject. The proper representation of my understanding would just be List<Object> and List<SomeObject> (w/out the extends). I thought extends helped me solve a problem which they don't. So here's where my real problem lies:

public interface DogKennel {
  public List<Dog> getDogs();
}

public class GreyHoundKennel implements DogKennel {

  protected List<GreyHound> greyHounds;

  public List<GreyHound> getGreyHounds() {
    return this.greyHounds;
  }

  public List<Dog> getDogs() {
    // Is there no way to handle this with generics
    // w/out creating a new List?
    return getGreyHounds(); //compiler error
  }

}
like image 807
andersonbd1 Avatar asked Jul 15 '09 18:07

andersonbd1


People also ask

What is a generic list Java?

Description. Java generics provides a way to parameterize types, say class MyClass<T> { ... } This allows the user to substitute an arbitrary Java Class for T when a MyClass object class is instantiated. Generics were introduced in Java 1.5.

What is generics in Java with simple example?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

Is ArrayList a generic type?

Both ArrayList and vector are generic types.


1 Answers

This declaration:

List<?> getOuterList() { }

is telling the compiler "I really don't know what kind of list I'm going to get back". Then you essentially execute

list<dunno-what-this-is>.add((MyObject)myObject)

It can't add a MyObject to the List of something that it doesn't know what type it is.

This declaration:

protected List<? extends Object> getOuterList() { ... }

tells the compiler "This is a list of things that are subtypes of Object". So again, of course you can't cast to "MyObject" and then add to a list of Objects. Because all the compiler knows is that the list can contain Objects.

You could however, do something like this:

List<? super MyObject>.getOuterList() { ... }

and then successfully add a MyObject. That's because now the compiler knows the List is a list of MyObject, or any supertype of MyObject, so it can surely accept MyObject.

Edit: As for your DogKennel example, this code snippet I think does what you want:

protected List<GreyHound> greyHounds;

// We only want a List of GreyHounds here:
public List<GreyHound> getGreyHounds() {
    return this.greyHounds;
}

// The list returned can be a List of any type of Dog:
public List<? extends Dog> getDogs() {
    return getGreyHounds();
}
like image 117
Ogre Psalm33 Avatar answered Sep 30 '22 20:09

Ogre Psalm33