简体   繁体   中英

What are these things in my method signature called? Generics?

I have a method signature that sorts a given map by values.

public static <K extends Comparable<K>, V extends Comparable<V>> Map<K,V> sortByValues(Map<K,V> map){

I am trying to understand the terminology for the things in this method signature. I get the public , static , Map<K,V> , the function name and the parameter part.

My confusion is on the <K extends Comparable<K>, V extends Comparable<V>> part. It's purpose is to define what K and V are in the context of the method, correct? What is the proper term to describe this?

Any recommended readings or articles on Generics?

Yes, K and V here are generic type parameters . To be more specific, as @aruisdante points out in comments, they are bounded type parameters because they specify a bound that the parameterized types must satisfy - namely that they both must implement Comparable.

It seems that your question is about the parameter in general though, not specifically about bounded parameters. You should definitely do some reading on your own, as you're asking about a big (and important) topic , but I'll take a stab at introducing it:

You might be familiar with seeing type parameters in a different context - Map<String, Integer> : <String, Integer> here are type parameters as well, and they specify that the keys in this map are String s and the values in it are Integer s. In the context of a method declaration, type parameters specify what the return type will be. This means you can write generic methods that return different types each time they're called, depending on what you pass in:

Note that the K and V are the type parameters on both the method itself and on the parameter passed in: This tells Java to determine K and V by looking at the key and value types of the map passed in, returning a map with the same types. If you call sortByValue(fooMap) and fooMap is a Map<String, FooType> , it's going to return a Map <String, FooType> , and if fooMap is a Map<Integer, BarType> , you'll get a Map<Integer, BarType> back.

For a clearer example, consider:

public <T> foobar(T t) {  }

Here the type parameter is unbounded - meaning that T can be any class, so you can pass an object of any class in as a parameter and get an object of the same type returned. Or

public<T> convertTo(Object o, Class<T> clazz) { } 

Here, you can pass in an object of any class as the first parameter, and as the second parameter a Class object that determines what T will be. So you can do:

Fooclass s = convertTo(someObject, Fooclass.class) 

which, as you can probably imagine, can be a very useful pattern.

They are examples of Parameterized Types according to the JLS Chapter 4. Types, Values, and Variables which says in part,

A generic class or interface declaration C ( §8.1.2 , §9.1.2 ) with one or more type parameters A1,...,An which have corresponding bounds B1,...,Bn defines a set of parameterized types, one for each possible invocation of the type parameter section.

Each parameterized type in the set is of the form C where each type argument Ti ranges over all types that are subtypes of all types listed in the corresponding bound. That is, for each bound type Si in Bi, Ti is a subtype of Si[F1:=T1,...,Fn:=Tn].

...

Given a type declaration specifier immediately followed by a type argument list, let C be the final Identifier in the specifier.

The way I see generics is the same way I see classes, only for types and methods. They generalize methods and data structures to natively support all bounded types.

Instead of coding the same object with the same methods over and over again it says "Okay guys, whatever class you'll tell me in the < > , I'll understand".

Suppose you want to write a binary search in an array of unknown object... you can write the following signature:

public boolean binarySearch(Object[] array)...

But what if you wanted the method to be accessed by only certain types of data (types that are compareable to each other)? this is how you would accomplish that:

public <T extends Comparable<T>> boolean binarySearch(T[] array)...

Which is read like: "This is a public method that receives only arrays which contain objects (we'll call them T) which implement the Comparable interface to the same classes (T).

Not only classes can be extended in generics, but interfaces as well (just like the example above).

For data structures like

Vector<Integer> v;

It means the Vector v will only hold Integer objects and not other types.

Wildcards have the same principle in bounding the object for example:

Vector<? extends Person> v;

That vector v is going to hold only classes whom super-class is Person.

This

Vector<?> v;

is roughly equivalent to this

Vector<Object> v;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM