Breaking java generics naming convention? [duplica

2019-02-02 23:45发布

This question already has an answer here:

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);
}

7条回答
Animai°情兽
2楼-- · 2019-02-02 23:56

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.

查看更多
smile是对你的礼貌
3楼-- · 2019-02-03 00:03

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.

查看更多
4楼-- · 2019-02-03 00:07

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/

查看更多
老娘就宠你
5楼-- · 2019-02-03 00:08

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.
查看更多
爷的心禁止访问
6楼-- · 2019-02-03 00:09

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);
}
查看更多
劫难
7楼-- · 2019-02-03 00:10

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).

查看更多
登录 后发表回答