The Java Language Specification states that a normal annotation is in the format
NormalAnnotation:
# TypeName ( ElementValuePairsopt )
A single-element annotation is in the format:
SingleElementAnnotation:
# Identifier ( ElementValue )
I do not understand, why this inconsistency, why is a normal annotation a TypeName and a single element annotation an Identifier? I believe the reference to Identifier might be a mistake in the specification since Identifier is not qualified and javac accepts AnnotationDeclarations that are qualified, for both normal annotations and single element annotations.
The reference to Identifier is a mistake in the specification since an identifier cannot be qualified (you can write #java.lang.SuppressWarnings("unchecked") but java.lang.SuppressWarnings is not a legal identifier). Javac accepts AnnotationDeclarations that are qualified, for both normal annotations and single element annotations. The mistake appears to be recently introduced; older versions of the JLS do not have this problem.
I think there is a mistake in the grammar documentation. The single annotation-element and the marker annotations are shorthand for the normal annotation.
You can also see the Java 1.5/1.6 specification: http://docs.oracle.com/javase/specs/jls/se5.0/html/interfaces.html#9.7
The single-element annotation is indicated as:
SingleElementAnnotation:
# TypeName ( ElementValue )
The tutorial is stating that Identifiers and TypeNames are two different things. From a programming perspective they are not. But from a logical perspective they could be, with the right analogy.
Starting with TypeName: Data types (Not counting primitive) and classes usually have more than one methods and/or attributes. So in a way, TypeName is kind of like the name of a class or a data type, which it kind of is.
On to Identifier: An Identifier is used to name or describe ONE variable or ONE class. In the right context, an Identifier can be associated with a single thing, like a int value, while a TypeName can represent an int and a String in one class.
int Identifier = 90; //Identifier represents an int value
class TypeName{
int i;
String s;
} //TypeName represents an int value and a String
TypeName MyNew = new TypeName(); //MyNew references to a TypeName, holding more
//than one value
This is very discreet logic, so if the logic does not make sense to you at first glance, the author may have changed the names for clarity, to make them a bit different. But no matter what the author calls them, they are the same thing, just worded differently.
It's a matter of semantics (and fairly pedantic semantics at that).
Consider a NormalAnnotation, such as #SuppressWarnings(value={"foo","bar")), where the SuppressWarnings (the TypeName) resolves to an annotation class that has a member named value.
Now consider a SingleElementAnnotation, such as #SuppressWarnings({"foo","bar")). The Identifier (SuppressWarnings) is the name of an interface, but there is nothing that says the one parameter should be assigned to value.
So, you cannot directly parse that sequence of characters as a NormalAnnotation; it doesn't have a correctly formatted ElementValuePairs. However, if you insert value=, between the opening parenthesis and the start of the parameter, then you get something that is parseable as a NormalAnnotation.
Likewise for MarkerAnnotation. It is missing the parenthesis required by the NormalAnnotation.
The Identifier needs to be a value that when used in the NormalAnnotation will yield a TypeName.
The NormalAnnotation has a number of restrictions on it, such as:
It is a compile-time error if TypeName does not name an annotation type that is accessible (§6.6) at the point where the annotation is used.
Until the SingleElementAnnotation or MarkerAnnotation is transformed into a NormalAnnotation, SuppressWarnings is just an Identifier and only needs to conform to the definition of Identifier. Note that TypeNames can be qualified, such as java.lang.SuppressWarnings, but Identifiers cannot.
I believe the intent was that MarkerAnnotation and SingleElementAnnotation should use simple names (Identifiers) rather than fully qualified names (TypeNames). So technically speaking #Override is ok, #java.lang.Override is incorrect, but #java.lang.Override() would be allowed. Every compiler I can get my hands on allows the latter. That makes the distinction rather moot for nearly everyone.
Related
I would like to ask if it is possible in Java 8+ to declare a generic bound T so that it extends superclass/superinterface U (which could be Object, or Serializable) but breaks compilation if T extends L (which must extend U first).
I have found this problem using filter range objects: one of my developers invoked the wrong method and spent much time questioning on why it was giving inconsistent results. So I wanted to help her changing the method signature, someway, to early detect that she is using wrong code.
I will display my example case in a very simplified way. We are talking about tables and dynamic filters.
#Displays a text "[field name] is equal to [value]"
#Value (T) must be Oject
#Internally uses Object::toString
#Null shows blank string
public static String <T> localizeEq(Localizable fieldName, T value);
<LocalDate> localize(forI18nLabel("DATE_OF_BIRTH_LABEL",dateOfBirth)
"Date of birth equals 01/01/1900" (en)
"syntymäaika on 01/01/1990" (fi)
#Additional diplays for "ge, gte, le..."
#Overload methods not displayed
#SimpleFilter is {op:"ge|ge|eq...",value:""}}
#The effective display depends on the op attribute
#Example "[field name] is [operator] [value]"
#Example "[field name] is less or equal than [upper]"
#If <filter != null but filter.op == null || filter.value> the method returns null
public static String <T> localize(Localizable fieldName, SimpleFilter<T> filter)
#localize(forI18nLabel("SALARY"),salaryFilter)
#salaryFilter = {op:"lt",value:10000}
#Salary is less than 10000 (en)
Now the problem is that the the upper bound U of my generics is Serializable and developer inadvertently invoked localizeEq, which accepts atomic values, with a parameter of type SimpleFilter<?> that extends Serializable. The method localizeEq builds a filter text "[field name] is equal to {op:null,value:null}".
The main issue is the null check. Methods that operate on atomic values (e.g. localizeEq, localizeNe) check if the parameter is null. Methods that operate on complex filters check that either the filter parameter is null or its value is null before going on.
That is the reason of the question. Obviously I can (will amend my code in order to) inspect the type of the value parameter when the method is invoked but has three drawbacks:
Developers find it only at runtime
Developers find the problem only when value is not null
Nobody in my company runs automated tests, so they will find out only when kickstarting the entire application and setting a non-null value to the filter. Once a manual test is done, it is never repeated
[Edit]
For my specific case there is another trick, but it involves creating more than a dozen overloaded deprecated methods:
#Deprecated
public static String localize[Eq|Ne...](Localizable fieldName, SimpleFilter<?> value){ throw new UnsupportedOperationException("Wrong method");}
[Edit 3]
The code is on Gist. Please note that in repository code we statically import SimpleFilter.filter or LocalDateRangeFilter.filter methods. In the question it is assumed that localize(Localizable,SimpleFilter) is part of the same class than other methods. And please note there are a few other *RangeFilter classes to support Joda Time, Java Util Date and NumericRange in our repository. They all suffer same issue.
I would like to focus anyway on the scope of the question: forbidding extension in generic, which seems not possible in the JLS.
I would like to ask if it is possible in Java 8+ to declare a generic
bound T so that it extends superclass/superinterface U (which could be
Object, or Serializable) but breaks compilation if T extends L (which
must extend U first).
The T in your pseudocode seems to be a type parameter, not a bound. Bounds are something different, and in fact, putting a bound on T seems to be what you are asking about. Indeed, without one -- in particular, without a lower bound -- your localizeEq() method is not gaining anything from being generic. As it stands, that method would be clearer if you just got rid of T altogether, and declared the second parameter to be of type Object (which would be equivalent to the current code) or Serializable or whatever.
I take it that the method was made generic in hopes of somehow using its type parameter to exclude arguments of certain subtypes, but that is not possible in Java, because
lower type bounds are inclusive, not exclusive
lower type bounds limit types meeting the bound to a single line of inheritance, which seems inconsistent with your intent
Now the problem is that the the upper bound U of my generics is
Serializable and developer inadvertently invoked localizeEq, which
accepts atomic values, with a parameter of type SimpleFilter<?> that
extends Serializable. The method localizeEq builds a filter text
"[field name] is equal to {op:null,value:null}".
If one is not supposed to pass a SimpleFilter to the localizedEq() method then I'd say that you have a design flaw here. You could catch violations at runtime, of course, but the type system does not provide a way to express the compile-time constraint you're looking for.
For my specific case there is another trick, but it involves creating more than a dozen overloaded deprecated methods:
Indeed, overloading is probably the best available solution, but I would suggest approaching it from the other direction. Instead of adding overloads for localizeEq, localizeNe, etc., deprecate the existing versions of those methods and instead overload localize with a version or versions that provide the wanted behavior for arguments that are not SimpleFilters.
What should we expect from the following name? : mGage Program
if I camelCase this it will be mGageProgram and if I generate (in eclipse) the getters and setters I will get the following:
public String getmGageProgram() {
return mGageProgram;
}
public void setmGageProgram(String mGageProgram) {
this.mGageProgram = mGageProgram;
}
Which to me doesn't seem right as I was expecting the getMGageProgram() and setMGageProgram(value).
Are these getters/setters names alright?
According to 8.8: Capitalization of inferred names of the JavaBeans API specification
the names generated from the IDE are correct.
they are 100% correct :) but conventions differ among programmers , for me its method names in camel casing not variables. as for syntax its correct :)
I’d like to provide just a little more depth on what the spec says. It specifies how we get from the name of a getter and/or a setter to a property name. The interesting quote in this context is:
… to support the occasional use of all upper-case names, we check if
the first two characters of the name are both upper case and if so
leave it alone.
It’s from section 8.8: Capitalization of inferred names.
One example given is that URL (as in getURL or setURL) becomes (or stays) URL (not uRL).
So the method names that you and I would have expected, getMGageProgram and setMGageProgram, would have implied a property named MGageProgram with an upper case M. Since we wanted mGageProgram we need to use lower case m in the names of the getter and the setter.
The rules as I read them thus really allow you to use a lowercase letter right after get or set in any getter or setter name. This came as a peculiar surprise to me. Of course it’s not an option that we want to exploit in cases where we don’t have to.
Link: JavaBeans Spec download page
This question already has answers here:
Generic type parameter naming convention for Java (with multiple chars)?
(5 answers)
Closed 7 years ago.
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);
}
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).
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.
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.
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.
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/
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...
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);
}
Let's say I have:
class A {
Integer b;
void c() {}
}
Why does Java have this syntax: A.class, and doesn't have a syntax like this: b.field, c.method?
Is there any use that is so common for class literals?
The A.class syntax looks like a field access, but in fact it is a result of a special syntax rule in a context where normal field access is simply not allowed; i.e. where A is a class name.
Here is what the grammar in the JLS says:
Primary:
ParExpression
NonWildcardTypeArguments (
ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
Identifier { . Identifier }[ IdentifierSuffix]
BasicType {[]} .class
void.class
Note that there is no equivalent syntax for field or method.
(Aside: The grammar allows b.field, but the JLS states that b.field means the contents of a field named "field" ... and it is a compilation error if no such field exists. Ditto for c.method, with the addition that a field c must exist. So neither of these constructs mean what you want them to mean ... )
Why does this limitation exist? Well, I guess because the Java language designers did not see the need to clutter up the language syntax / semantics to support convenient access to the Field and Method objects. (See * below for some of the problems of changing Java to allow what you want.)
Java reflection is not designed to be easy to use. In Java, it is best practice use static typing where possible. It is more efficient, and less fragile. Limit your use of reflection to the few cases where static typing simply won't work.
This may irk you if you are used to programming to a language where everything is dynamic. But you are better off not fighting it.
Is there any use that is so common for class literals?
I guess, the main reason they supported this for classes is that it avoids programs calling Class.forName("some horrible string") each time you need to do something reflectively. You could call it a compromise / small concession to usability for reflection.
I guess the other reason is that the <type>.class syntax didn't break anything, because class was already a keyword. (IIRC, the syntax was added in Java 1.1.)
* If the language designers tried to retrofit support for this kind of thing there would be all sorts of problems:
The changes would introduce ambiguities into the language, making compilation and other parser-dependent tasks harder.
The changes would undoubtedly break existing code, whether or not method and field were turned into keywords.
You cannot treat b.field as an implicit object attribute, because it doesn't apply to objects. Rather b.field would need to apply to field / attribute identifiers. But unless we make field a reserved word, we have the anomalous situation that you can create a field called field but you cannot refer to it in Java sourcecode.
For c.method, there is the problem that there can be multiple visible methods called c. A second issue that if there is a field called c and a method called c, then c.method could be a reference to an field called method on the object referred to by the c field.
I take it you want this info for logging and such. It is most unfortunate that such information is not available although the compiler has full access to such information.
One with a little creativity you can get the information using reflection. I can't provide any examples for asthere are little requirements to follow and I'm not in the mood to completely waste my time :)
I'm not sure if I fully understand your question. You are being unclear in what you mean by A.class syntax. You can use the reflections API to get the class from a given object by:
A a = new A()
Class c = a.getClass()
or
Class c = A.class;
Then do some things using c.
The reflections API is mostly used for debugging tools, since Java has support for polymorphism, you can always know the actual Class of an object at runtime, so the reflections API was developed to help debug problems (sub-class given, when super-class behavior is expected, etc.).
The reason there is no b.field or c.method, is because they have no meaning and no functional purpose in Java. You cannot create a reference to a method, and a field cannot change its type at runtime, these things are set at compile-time. Java is a very rigid language, without much in the way of runtime-flexibility (unless you use dynamic class loading, but even then you need some information on the loaded objects). If you have come from a flexible language like Ruby or Javascript, then you might find Java a little controlling for your tastes.
However, having the compiler help you figure our potential problems in your code is very helpful.
In java, Not everything is an object.
You can have
A a = new A()
Class cls = a.getClass()
or directly from the class
A.class
With this you get the object for the class.
With reflection you can get methods and fields but this gets complicated. Since not everything is an object. This is not a language like Scala or Ruby where everything is an object.
Reflection tutorial : http://download.oracle.com/javase/tutorial/reflect/index.html
BTW: You did not specify the public/private/protected , so by default your things are declared package private. This is package level protected access http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
In some interfaces I wrote I'd like to name generic type parameters with more than one character to make the code more readable.
Something like....
Map<Key,Value>
Instead of this...
Map<K,V>
But when it comes to methods, the type-parameters look like java-classes which is also confusing.
public void put(Key key, Value value)
This seems like Key and Value are classes. I found or thought of some notations, but nothing like a convention from Sun or a general best-practice.
Alternatives I guessed or found...
Map<KEY,VALUE>
Map<TKey,TValue>
Oracle recommends the following in Java Tutorials > Generics > Generic Types:
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 lesson.
I'd stick to it to avoid the confusion among the developers and possible maintainers.
Append Type
A good discussion can be found in the comments on the DZone page, Naming Conventions for Parameterized Types.
See the comment by Erwin Mueller. His suggestion makes perfect obvious sense to me: Append the word Type.
Call an apple an apple, a car a car. The name in question is the name of a data type, right? (In OOP, a class essentially defines a new data type.) So call it a “Type”.
Mueller’s example, drawn from the original post’s article:
public interface ResourceAccessor < ResourceType , ArgumentType , ResultType > {
public ResultType run ( ResourceType resource , ArgumentType argument );
}
Append T
A duplicate Question provides this Answer by Andy Thomas. Note the excerpt from Google’s style guide that suggests a multi-character type name should end in a single uppercase T.
Yes, you can use multi-character names for type variables, as long as they are clearly distinguished from class names.
This differs from the convention suggested by Sun with the introduction of generics in 2004. However:
More than one convention exists.
Multi-character names are consistent with other Java styles, such as Google’s style for Java.
The readable names are (surprise!) more readable.
Readability
In some interfaces I wrote I’d like to name generic type parameter with more than one character to make the code more readable.
Readability is good.
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> {
or, with Google’s multi-character convention:
public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT>
implements IEventProducer<ListenerT, EventT> {
public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT>
implements IEventProducer<ListenerT, EventT> {
Google style
The Google Java Style Guide 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).
Issues
“Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name.” – from the Oracle tutorials, “Generic types”
Single-character names are not the only way to distinguish type parameters from class names, as we’ve seen above.
Why not just document the type parameter meaning in the JavaDoc?
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.)
Multi-character type parameter names don’t follow the Oracle convention!
Many of Sun’s original conventions are followed nearly universally in Java programming.
However, this particular convention is not.
The best choice among competing conventions is a matter of opinion. The consequences of choosing a convention other than Oracle’s in this case are minor. You and your team can choose a convention that best meets your needs.
You can use javadoc to at least give users of your generic class a clue. I still don't like it (I agree with #chaper29) but the docs help.
eg,
/**
*
* #param <R> - row
* #param <C> - column
* #param <E> - cell element
*/
public class GenericTable<R, C, E> {
}
The other thing I have been known to do is use my IDE to refactor a class breaking the convention. Then work on the code and refactor back to single letters. Makes it easier for me anyway if many type parameters are used.
The reason why the official naming convention reccommends using single letter is the following:
Without this convention, it would be difficult to tell the difference
between a type variable and an ordinary class or interface name.
I think with modern IDEs that reason is no longer valid as eg. IntelliJ Idea shows generic type parameters with different colors than regular classes.
Code with generic type as displayed in IntelliJ Idea 2016.1
Because of that distinction I use longer descriptive names for my generic types, with same convention as regular types. I avoid adding prefixes and suffixes such as T or Type as I consider them unnecessary noise and no longer needed to visually distinguish generic types.
Note: As I am not a user of Eclipse or Netbeans, I do not know whether they offers a similliar feature.