24

I have an interface whose declaration is as follows:

/**
* @param T - the type of entity.
* @param C - the type of entity container will be returned.
*/
public interface FindByNamedQuery<T extends Serializable, C extends Collection<T>> extends Command {
    C executeNamedQuery(String namedQuery);
}

I wonder if I can (should) break the Java naming convention to do this:

public interface FindByNamedQuery<ENTITY_TYPE extends Serializable, RETURNED_CONTAINER extends Collection<ENTITY_TYPE>> extends Command {
    RETURNED_CONTAINER executeNamedQuery(String namedQuery);
}
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Genzer
  • 2,921
  • 2
  • 25
  • 38
  • 2
    You already have your `@param` tags to give users information on the type parameters. – ColinD May 26 '11 at 18:46
  • 2
    My intent is to make the declaration more descriptive. – Genzer May 26 '11 at 18:53
  • 2
    You have the right idea with making it more descriptive, limiting type parameters to 1 character in a situation as complex as this is silly, IMO. The only thing wrong with your proposed convention is that `ALL_CAPS` is indicative of a constant. – Allen Rice May 26 '11 at 18:55
  • 4
    @ColinD, you have the same for arguments to a method but you dont go around naming those `a`, `b`, `c`, etc. – Allen Rice May 26 '11 at 18:58

7 Answers7

27

I am beginning to disagree with the single-character convention, after using it since the mid-1990s.

I find the readable names more readable. This is helpful in understanding both the implementation and interface of generic types.

The ambiguity problem seems overstated for Java. Few class names are all-uppercase. Constants are not used in the same context as class names.

It's true that the @param JavaDoc elements can provide a longer description. But it's also true that the JavaDocs are not necessarily visible. (For example, there's a content assist in Eclipse that shows the type parameter names.)

For example, compare :

public final class EventProducer<L extends IEventListener<E>,E> 
    implements IEventProducer<L,E> {

to:

public final class EventProducer<LISTENER extends IEventListener<EVENT>,EVENT> 
    implements IEventProducer<LISTENER, EVENT> {

Although the single-character names have been recommended as a convention by Sun/Oracle, conventions can be changed. The consequences of challenging this convention are minor. If you and your team prefer meaningful names for your type parameters, I personally would go for it.

Edit (2015)

Google style for Java allows both single-letter names and multi-character class-like names ending in T.

5.2.8 Type variable names

Each type variable is named in one of two styles:

  • A single capital letter, optionally followed by a single numeral (such as E, T, X, T2)

  • A name in the form used for classes (see Section 5.2.2, Class names), followed by the capital letter T (examples: RequestT, FooBarT).

Charles Follet
  • 827
  • 1
  • 10
  • 28
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • I agree generally, but I think adding the "Type" suffix is the best solution I've heard. To me that seems clearer than adding "T" since it's a bit less esoteric. Using all caps with underscores is an odd choice since it's so different and usually used for constants and enums. It wouldn't be confused with anything else because its weirdness would demand you to figure out exactly what it is. But that just seems like unnecessary cognitive overhead when "Type" is clearer. – Drew Nutter Aug 21 '19 at 16:58
  • 1
    @Drew - There can be actual types named the same, and used in the same context. That can make it more difficult to recognize whether a type is a parameterized type or not. – Andy Thomas Aug 21 '19 at 18:03
24

I wonder if I can (should) break the java naming convention to do this:

No, this should be avoided as it becomes easier to confuse the type parameters with constants and other identifiers.

Here's a quote from the official trail on generics:

Type Parameter Naming Conventions

By convention, type parameter names are single, uppercase letters. This stands in sharp contrast to the variable naming conventions that you already know about, and with good reason: Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name.

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

You'll see these names used throughout the Java SE API and the rest of this tutorial.

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 1
    The C#'s way of avoiding the confusion between type variables and class/interface names seems more reasonable to me. It leads to code that is easier to understand, especially when several type parameters are present. – brabec Jun 24 '11 at 12:07
  • 3
    How difficult could it be to tell the difference between a type and a class name? Seriously. I mean, most of the time you read code directly from the IDE (which highlights generic names with a different color). Also, if you are reading it from a dumb text editor, it's easy to just look at the signature of the class and keep in mind, for a couple of minutes, which names are referring to a generic type. – Cristian Jan 30 '14 at 00:37
  • isn't Void also a convention sometimes? http://stackoverflow.com/questions/643906/uses-for-the-java-void-reference-type "Void has become convention for a generic argument that you are not interested in." – barlop Feb 12 '15 at 06:27
  • @barlop, I think you're confusing type *argument* with type *parameter*. – aioobe Feb 12 '15 at 07:48
  • @Cristian, +1, often these type of "problems" are symptoms of too large classes and/or methods. – aioobe Feb 12 '15 at 08:16
  • @aioobe ah you're right, I was wrongly thinking Void could occur in a formal parameter. Though i'd note re the term 'parameter' I see you mean formal parameter but there is a term 'actual parameter' which means argument. http://programmers.stackexchange.com/questions/186293/why-are-actual-parameters-called-arguments – barlop Feb 13 '15 at 03:07
10

Using TDescription is pretty common in C#. It maintains the T name but is also descriptive at the same time, like so:

public interface FindByNamedQuery<
    TEntityType extends Serialiazble, 
    TReturnedContainer extends Collections<TEntityType>> extends Command 
{     
    TReturnedContainer executeNamedQuery(String namedQuery); 
} 

As others have said ALL_CAPS almost always indicates a constant.

IMO, "it would be difficult to tell the difference between a type variable and an ordinary class or interface name." does not apply here, because the T prefix easily identifies it as a type variable.

Again, this is C# but see MSDN: Naming Conventions For Generics

In all other cases, the official Microsoft guidelines for generic naming conventions are:

  • Name generic type parameters with descriptive names, unless a single letter name is completely self explanatory and a descriptive name would not add value.

    public interface ISessionChannel<TSession> 
    {...}
    
    public delegate TOutput Converter<TInput,TOutput>(TInput from);
    
  • Consider indicating constraints placed on a type parameter in the name of parameter. For example, a parameter constrained to ISession may be called TSession.
Allen Rice
  • 19,068
  • 14
  • 83
  • 115
  • I use also A prefix for abstract class, I prefix for interface ant T prefix for generic type seems valid to me ;-) – Betlista Oct 11 '13 at 13:45
4

The compiler might not complain, but your teammates might not appreciate you using what looks to be a constant in a place where they're expecting a type parameter.

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
3

I think this is the gripe of many people using generics. I don't quite agree with Sun's statement that if you use a full fledged name then it will confuse with an existing class name or something else. In that case we can start the placeholder name with a dollar like this:

public class HashMap<$Key,$Value> implements Map<$Key,$Value>{}

No one in their sane mind names a class starting with a dollar sign. And a dollar sign also is used to denote a placeholder many templating languages velocity, struts, spring, etc. I think this is the way to go.

I have got more details about this and the reasoning behind not having to use a single letter notation in my blog post if anyone is interested.

http://readsethu.wordpress.com/2012/05/23/a-generic-class-and-why-is-it-confusing/

sethu
  • 8,181
  • 7
  • 39
  • 65
  • Thanks for your answer. It's been a while since I posted this quesiton. I've found that in Android library, type parameter are named the same way with class name (for example: `AsyncTask`) – Genzer May 26 '12 at 16:21
1

Like Allen before, my advice comes more from C# (which I use extensively since 5 months) than Java (which I played with, but it never went very far...), but I find Java and C# code quite similar in spirit (that is, when compared by, say, C++)

Anyway, when using a C#/Java generic (or a C++ template) on a simple type, I usually use T:

// C++
template<typename T>
class MyClass { /* ... */ } ;
// C#
public MyClass<T> { /* etc. */ }
// Java
public MyClass<T> { /* etc. */ }

Usually, the type T goes with the class, so there is no need to describe it more.

But when really describing the type adds to the code clarity, I do it.

Or when I have two or more types in the same generic/template declaration, it helps to make the difference between two types. For example (real life example in C#) :

// C++
template<typename T_Data, typename T_Underlying>
class MyClass { /* ... */ } ;
// C#
public MyClass<T_Data, T_Underlying> { /* etc. */ }
// Java
public MyClass<T_Data, T_Underlying> { /* etc. */ }

This way, it is easy to make the difference between the two typenames in the code, where T and U are, well... kinda anonymous: For those using Visual C++, going in debug inside Dinkumware's STL code, full of T, _U, and other mono-letter typenames can be quite frustrating... I guess the same goes for C# or Java code.

You will note that in each case (C++, Java or C#), I don't follow the convention somewhere in my type namings: The reason is that sometimes, you just have to try something else instead of following the herd, even if in the end, you'll find you're wrong.

In the current case, the violation of naming convention is not critical (there are worst problems in Java than this petty crime), and at the very last, you'll learn personally and exactly WHY it is wrong, instead of quoting old documents.

And if you find in the end you're right, well...

Community
  • 1
  • 1
paercebal
  • 81,378
  • 38
  • 130
  • 159
0

I would name type variables similar to types, in camel casing, but prefixed with "_".

public interface FindByNamedQuery
    <_EntityType extends Serialiazble, 
     _ReturnedContainer extends Collections<_EntityType>> 
    extends Command 
{
    _ReturnedContainer executeNamedQuery(String namedQuery);
}
irreputable
  • 44,725
  • 9
  • 65
  • 93
  • If I do not like something in naming conventions, it is naming private fields starting with _, this is the same (just an opinion). – Betlista Oct 11 '13 at 13:48