Understanding Java generics. Type parameter conven

2020-05-19 04:11发布

问题:

The most commonly used type parameter names are:

E - Element (used extensively by the Java Collections Framework)

K - Key

N - Number

T - Type

V - Value

S,U,V etc. - 2nd, 3rd, 4th types

I don't seem to quite understand what exactly does every letter correspond to. I understand that each letter represents just a convention but what does 2nd, 3rd and 4th type mean exactly? When should I use what? On their official tutorials website it doesn't give further information.

回答1:

Some examples:

  • Map<K, V>: A map usually assigns Values to Keys. These are special kinds of types, so they are used here.
  • List<E>: A list contains Elements. It's a convention that they are called elements. On the other hand, T would also be acceptable here.
  • Formatter<T>: A formatter can format any Type. It's not really an element, nor a key, nor a value, so T is the correct letter here.
  • Triplet<T, U, V>: A triplet for arbitrary types. Since the type definition does not know anything about the types that will be filled in later, it uses just the T for the first type, followed by the next letters in alphabetical order.


回答2:

I strongly recommend longer names, especially when you have more than one type parameter.

public class MyMap<Key, Value> {...}

If you insist on a convention, you may want to add "Type" to the end of the name, like

public class MyMap<KeyType, ValueType> {...}

(Though I prefer to just have the name without a suffix. The name should be UpperCamelCase)



回答3:

As you know, the letters don't mean anything in themselves and are just conventions to make reading the code a bit easier. The "2nd, 3rd and 4th types" bit just means when you have a parameterised type with multiple arguments you should call those arguments S, T, U, V etc. For example

class MyClass<S, T, U> {
}

is a class with three type parameters.

Obviously you don't have to use S, T and U. If a more meaningful convention can be used then you should do so, for example

class Car<W, E, P> {
}

could be a Car class parameterised on wheel, engine and paint type.

EDIT: As the other answer pointed out, even better would be:

class Car<WheelType, EngineType, PaintType> {
}


回答4:

I don't seem to quite understand what exactly does every letter correspond to. I understand that each letter represents just a convention but what does 2nd, 3rd and 4th type mean exactly?

The reason that you don't "quite understand what exactly does every letter correspond to" is that the use of single letter type parameter names is an informal convention. The letters don't and cannot have fixed meanings. You are expected to read the javadocs (and if necessary, the code) to figure out what the letters mean in the context of the classes. In most cases, there is some kind of meaning intended by the code author. Just figure it out.

When should I use what?

If you are following a coding standard that says something on this subject, then do what it says. Otherwise:

  • try to be consistent with the emerging conventions of your existing codebase as you see them, and
  • use your common sense, and do what gives the most readable code.

On their official tutorials website it doesn't give further information.

That is correct.

The "official" Java style guide document has not been updated for ~10 years. On the one hand, it is a shame that Sun / Oracle no longer see formalizing style conventions as their role. On the other hand, I can understand why they don't. (There is no "value" to Sun, and the potential aggravation for the people involved is simply not worth it. If you've been in one of those pointless debates about the "right" place to put curly brackets, spaces and so on, and on, and on, you'll know what I mean.)



回答5:

I typically just represent the generic type as if it were a class name:

abstract class DAO<Entity, Id> {
   abstract Entity findById(Id id);
}

IMO, your code should be semantic almost to the point where it's like reading sentences instead of code. To me, this isn't very readable or semantic:

abstract class DAO<E, I> {
   abstract E findById(I id);
}

If all else just falls short, just call it what it is.



标签: java generics