Java Generics wildcards and their limitations

I have a two-part question

My book says: "If a wildcard is specified without the upper, then only methods of type Object can be called on the values โ€‹โ€‹of the wildcard type"

I have no idea what this can mean. What does it mean?

Also, what are the restrictions on the types of wild cards (unlimited and limited)? For example, if I have a link to MyClass<?> Or MyClass<? extends SomeOtherClass> MyClass<? extends SomeOtherClass> which methods I am not allowed to call through this link. I donโ€™t understand what the wild card allows or forbids me to do , which is probably why I donโ€™t understand the quote from this book.

I have an example for the second part:

 class SomeOtherClass { [...] } class MyClass<T> { [...] } class Test { public static void main(String[] arg) { MyClass<? extends SomeOtherClass> myClass = new MyClass<String>() // for instance what does the wild card reference limit me to in any way. In a general sence. } } 
+6
source share
3 answers

Wildcard restrictions (upper and lower) are often mandatory for collections and classes that return objects of a parameterized type.

You often hear about PECS , which means "Producer extends, Consumer super." I suggest you read the answer to this question to avoid duplicate answers.

  • To be more precise, when you define your wildcard with <? extends TheClass> <? extends TheClass> , you tell the compiler that the wildcard object is at least of type TheClass . Thus, you can use this object as an instance of TheClass and call any method suggested by this type.

  • Now that you define your wildcard as <? super TheClass> <? super TheClass> , you tell the compiler that the type of your wildcard object is implemented or extended by the type TheClass . This means that the type of the object cannot be TheClass , but TheClass can be used as an instance of your wildcard. Therefore, you cannot call anything this object, because its type is known only at run time, but you can pass the object to methods that expect a wildcard object.

Examples:

 private void foo(List<?> list) { Object o = list.get(0); // ok list.add(new Object()); // won't compile! // you cannot add anything, and only extract Object instances } private void foo(List<? extends TheClass> list) { Object o1 = list.get(0); // ok TheClass o2 = list.get(0); // ok list.add(new Object()); // won't compile! list.add(new TheClass()); // won't compile! // You are sure that the objects are of a subtype of TheClass, // so you can extract TheClass instances safely. However, you cannot // add anything to this list since its type is not known (may be // different from TheClass, so the compiler does not allow anything). } private void foo(List<? super TheClass> list) { Object o1 = list.get(0); // ok TheClass o2 = list.get(0); // won't compile! list.add(new Object()); // won't compile! list.add(new TheClass()); // ok // You are sure that the objects are of a type implemented by TheClass, // so you can add any TheClass instances to the list. However, you cannot // extract TheClass objects since the objects type may be just implemented // by TheClass, but different. } 
+9
source

Normal general;

 ArrayList<Man> list= new ArrayList<Man>(); list.put(man); Man m = list.get(0); 

Using a wildcard with an upper bound:

 ArrayList<? extends Person> list= new ArrayList<? extends Person>(); list.put(man); //Man is a person.. Person p = list.get(0); 

Using the template:

 ArrayList<?> list= new ArrayList<?>(); list.put(man); Object o = list.get(0); 

If you use a wildcard, you cannot know the general type of ArrayList, so you can only get Object from the list, which means that you are again using ArrayLists in the old way without generics.

0
source

For example, do you have <? extends MyClass> wildcard. This means that any class matching this pattern can be of type MyClass or any of its descendants. But since the only thing we know is a descendant of MyClass, we can only guarantee that the available methods of the MyClass class are callable.

For wildcards with an upper border of boron <>, the upper border will be the class Object. And this means that all we know is that the class extends Object, so only the methods that are guaranteed to be present in this class are those that are defined in the Object class.

0
source

Source: https://habr.com/ru/post/911178/


All Articles