Say I have something like this:
public class MyClass {
private static MyClass sInstance;
/**
*
* #return The {#link MyClass} application instance.
*/
public static MyClass getInstance() {
return sInstance;
}
}
IntelliJ gives me this warning:
'#link' pointing to containing class is unnecessary
What's the proper/conventional way to write this piece of Javadoc?
How would you write it?
In the JDK, they use {#code}. That does not make a clickable link, but you are already looking at the page that would be linked anyway.
For example (from String.java):
/**
* Initializes a newly created {#code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {#code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* #param original
* A {#code String}
*/
You only get the warning because the link won't go anywhere. Just change it to {#code MyClass} to keep the formatting but without the link.
Here are some example getInstance() methods from the JDK.
java.text.Collator:
/**
* Gets the Collator for the current default locale.
* The default locale is determined by java.util.Locale.getDefault.
* #return the Collator for the default locale.(for example, en_US)
* #see java.util.Locale#getDefault
*/
public static synchronized Collator getInstance() {
java.text.NumberFormat:
/**
* Returns a general-purpose number format for the current default
* {#link java.util.Locale.Category#FORMAT FORMAT} locale.
* This is the same as calling
* {#link #getNumberInstance() getNumberInstance()}.
*
* #return the {#code NumberFormat} instance for general-purpose number
* formatting
*/
public final static NumberFormat getInstance() {
Related
I have methods toSaveString(StringBuilder) and toSaveString() in several classes and thought of turning those into an interface. The first method would always have to be implemented and the second I could default because it basically only calls the first method every time with a new string builder and returns the resulting string. (Not what default is designed for, but bear with me.)
Now I wouldn't need to implement toSaveString() in the classes implementing the interface, but I would like to change its documentation nonetheless to match the class. Is there a way to achieve this without overriding the toSaveString() method in the implementing class? Because adding three lines to call the default method or five to copy the implementation seems redundant and easy to get errors mixed in.
Also feel free to leave comments about design alternatives here, but the question stays because it is interesting in its own right.
Look at the javadoc of the ArrayList#removeIf method:
/**
* #throws NullPointerException {#inheritDoc}
*/
#Override
public boolean removeIf(Predicate<? super E> filter) {
return removeIf(filter, 0, size);
}
It overrides its superclass Collection#removeIf method:
/**
* Removes all of the elements of this collection that satisfy the given
* predicate. Errors or runtime exceptions thrown during iteration or by
* the predicate are relayed to the caller.
*
* #implSpec
* The default implementation traverses all elements of the collection using
* its {#link #iterator}. Each matching element is removed using
* {#link Iterator#remove()}. If the collection's iterator does not
* support removal then an {#code UnsupportedOperationException} will be
* thrown on the first matching element.
*
* #param filter a predicate which returns {#code true} for elements to be
* removed
* #return {#code true} if any elements were removed
* #throws NullPointerException if the specified filter is null
* #throws UnsupportedOperationException if elements cannot be removed
* from this collection. Implementations may throw this exception if a
* matching element cannot be removed or if, in general, removal is not
* supported.
* #since 1.8
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
In your case, you can override only javadoc, and write something like this in the method body:
/**
* custom javadoc
*/
#Override
public boolean customMethod(Object parameter) {
return super.customMethod(parameter);
}
See also: Can I add code to an inherited method without overriding the whole method?
Each time you use String.format(), a new instance of java.util.Formatter is created that will be disposed afterwards.
Just because I was curious, I played around with that a bit to make the use of format() a little more efficient, by caching the Formatter object. Unfortunately, Formatter is not thread-safe, and any means of synchronisation would eat up any performance gain you can get from caching it.
Finally, I found the solution below:
import java.util.Formatter;
/*------------------------*\
====** Static Initialisations **===========================================
\*------------------------*/
/**
* The initial buffer size that is used by
* {#link #format(String, Object...)}
* and
* {#link #format(Locale, String, Object...)}
* (per thread): {#value}.
*/
public final static int FORMAT_INITIAL_BUFFERSIZE = 2048;
/**
* The cached
* {#link Formatter}
* instance.
*/
private static final ThreadLocal<Formatter> m_Formatter;
static
{
//---* The cached Formatter instance *---------------------------------
final Supplier<Formatter> initializer = () -> new Formatter( new StringBuilder( FORMAT_INITIAL_BUFFERSIZE ), Locale.getDefault( Locale.Category.FORMAT ) );
m_Formatter = ThreadLocal.<Formatter>withInitial( initializer );
}
/*---------*\
====** Methods **==========================================================
\*---------*/
/**
* Returns a formatted String using the specified
* {#link Locale},
* format String, and arguments.<br>
* <br>This method is meant as a replacement for the method
* {#link java.lang.String#format(String, Object...)};
* that implementation always uses a new instance of
* {#link Formatter}
* for each invocation. The implementation here uses a cached instance
* instead, and as {#code Formatter} is not inherently thread-safe, this
* cached instance is created and stored per thread, therefore no
* synchronisation is needed.<br>
* <br>The performance gain for this implementation is not that impressive
* when compared with that of
* {#link #format(String, Object...)},
* but still in the 10% range.
* {#code java.lang.String.format()}.
*
* #param locale The
* {#link Locale}
* that will be applied during formatting. If {#code locale} is
* {#code null} then no localisation is applied.
* #param format A format String with the syntax as described for the
* {#link Formatter}
* class.
* #param args The arguments referenced by the format specifiers in
* the {#code format} String. If there are more arguments than format
* specifiers, the extra arguments are ignored. The number of
* arguments is variable and may be zero. The maximum number of
* arguments is limited by the maximum dimension of a Java array as
* defined by <cite>The Java™ Virtual Machine
* Specification</cite>. The behaviour on a {#code null} argument
* depends on the conversion.
* #throws IllegalFormatException A format string contains an illegal
* syntax, a format specifier that is incompatible with the given
* arguments, insufficient arguments given the format string, or other
* illegal conditions occurred. For specification of all possible
* formatting errors, see the "Details" section of the
* {#code Formatter} class specification.
* #return A formatted String.
*
* #see java.util.Formatter
*/
#SuppressWarnings( "resource" )
public final static String format( final Locale locale, final String format, final Object... args ) throws IllegalFormatException
{
/*
* When this method StringUtils.format() is used inside an
* implementation of Formattable.formatTo() that in turn was called by
* this method already, the internal out buffer of the formatter
* contains already some text that has to be preserved.
*
* Therefore the current length of the out buffer is kept before new
* contents is added by the call to formatter.format(), and reset after
* the new formatted text was retrieved from that buffer.
*/
final var formatter = m_Formatter.get();
final var result = (StringBuilder) formatter.out();
final var currentPos = result.length();
formatter.format( locale, format, args );
final var retValue = result.substring( currentPos );
result.setLength( currentPos );
//---* Done *----------------------------------------------------------
return retValue;
} // format()
The cached Formatter instance is hold in an instance of java.lang.ThreadLocal, so each Thread has its own instance and no synchronisation is required.
So far it is working; extensive tests did not show any problems so far, and some (artificial) benchmarks show a performance gain of about 10% compared to the use of java.lang.String.format(); that gain is constant on any (class of) machine I ran the tests on.
An obvious disadvantage of this solution is that the memory footprint for each thread that uses my format() implementation is increased by around half a kB plus the size of the initial buffer (see the source).
But I can faintly remember some statements that using java.lang.ThreadLocal is evil, although I cannot remember any reason why … basically, you can boil it down to "there are rumours …".
Or not? Is there something that I missed about the use of java.util.ThreadLocal in the way I did?
Please do not discuss whether replacing String.format() with my solution might be useful or not: I just did it – as said – because I was curious whether it could made faster by caching the Formatter instance – nothing else.
Edit (based on some of the comments that have been added to the question):
That the Formatter instance will never be removed from the Thread is intended. But there is no need to keep the size of the associated StringBuilder at its current size when it was extended above the initial size.
There is an issue with ThreadLocal in the context of 'managed environments' (Application Servers and Web Servers) because there Threads are re-used, and therefore, the data stored in the ThreadLocal will never be garbage collected, as the ThreadLocal will never be released.
The Pointcut interface in Spring Framework consists of 2 methods:
public interface Pointcut {
/**
* Return the ClassFilter for this pointcut.
* #return the ClassFilter (never {#code null})
*/
ClassFilter getClassFilter();
/**
* Return the MethodMatcher for this pointcut.
* #return the MethodMatcher (never {#code null})
*/
MethodMatcher getMethodMatcher();
/**
* Canonical Pointcut instance that always matches.
*/
Pointcut TRUE = TruePointcut.INSTANCE;
}
The ClassFilter interface is already stating that, it is sole purpose is to decide whether a class can pass the filter or not:
/**
* Filter that restricts matching of a pointcut or introduction to
* a given set of target classes.
*
* <p>Can be used as part of a {#link Pointcut} or for the entire
* targeting of an {#link IntroductionAdvisor}.
*
* #author Rod Johnson
* #see Pointcut
* #see MethodMatcher
*/
public interface ClassFilter {
/**
* Should the pointcut apply to the given interface or target class?
* #param clazz the candidate target class
* #return whether the advice should apply to the given target class
*/
boolean matches(Class<?> clazz);
/**
* Canonical instance of a ClassFilter that matches all classes.
*/
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
What I do not understand is, why does the methods in the MethodMatcher interface again checks for class eligibility? Why the methods of this interface have the targetClass arguments?
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches. If this
* returns {#code false} or if the {#link #isRuntime()} method
* returns {#code false}, no runtime check (i.e. no.
* {#link #matches(java.lang.reflect.Method, Class, Object[])} call) will be made.
* #param method the candidate method
* #param targetClass the target class (may be {#code null}, in which case
* the candidate class must be taken to be the method's declaring class)
* #return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
/**
* Check whether there a runtime (dynamic) match for this method,
* which must have matched statically.
* <p>This method is invoked only if the 2-arg matches method returns
* {#code true} for the given method and target class, and if the
* {#link #isRuntime()} method returns {#code true}. Invoked
* immediately before potential running of the advice, after any
* advice earlier in the advice chain has run.
* #param method the candidate method
* #param targetClass the target class (may be {#code null}, in which case
* the candidate class must be taken to be the method's declaring class)
* #param args arguments to the method
* #return whether there's a runtime match
* #see MethodMatcher#matches(Method, Class)
*/
boolean matches(Method method, Class<?> targetClass, Object... args);
/**
* Canonical instance that matches all methods.
*/
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
The targetClass specified in MethodMatcher.matches(Method method, Class<?> targetClass)is not used for checking the eligibility of a target invocation class.
It is used for finding the most specific target method which is applicable to the target class for a given method (specified as a parameter). It also resolves issues with Java bridge methods.
Here is a sample matches method from org.springframework.aop.aspectj.AspectJExpressionPointcut class.
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
this.checkReadyToMatch();
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
ShadowMatch shadowMatch = this.getShadowMatch(targetMethod, method);
...
}
Here is the Javadoc from org.springframework.aop.support.AopUtils#getMostSpecificMethod
Given a method, which may come from an interface, and a target class used
in the current AOP invocation, find the corresponding target method if there is one. E.g. the method may be IFoo.bar() and the target class may be DefaultFoo. In this case, the method may be DefaultFoo.bar(). This enables attributes on that method to be found.
NOTE: In contrast to org.springframework.util.ClassUtils#getMostSpecificMethod, this method resolves Java 5 bridge methods in order to retrieve attributes from the original method definition.
I meet a problem when using A.class in program and it return java.lang.NullPointerException at run-time
This is my snipped code:
public synchronized boolean isDeviceEqual(IDevice dev) {
............
if( isDeviceInstanceOf(SimpleDevice.class) ) {
return dev instanceof IDevice
&& XXX();
}
............
}
public boolean isDeviceInstanceOf(Class cls) {
return cls.isAssignableFrom(mDeviceClass);
}
and NPE
java.lang.NullPointerException
at xxx/library/DeviceDescriptor.isDeviceInstanceOf(Ljava/lang/Class;)Z (:0:5)
at xxx/library/DeviceDescriptor.isDeviceEqual(LIDevice;)Z (:0:6)
with above NPE, it means that cls is null in this case but I can't explain why this happens so can anybody help me?
cls.isAssignableFrom(mDeviceClass) will throw a NullPointerException if mDeviceClass, which must be the case here, since you are sure that cls is not null.
/**
* Determines if the class or interface represented by this
* <code>Class</code> object is either the same as, or is a superclass or
* superinterface of, the class or interface represented by the specified
* <code>Class</code> parameter. It returns <code>true</code> if so;
* otherwise it returns <code>false</code>. If this <code>Class</code>
* object represents a primitive type, this method returns
* <code>true</code> if the specified <code>Class</code> parameter is
* exactly this <code>Class</code> object; otherwise it returns
* <code>false</code>.
*
* <p> Specifically, this method tests whether the type represented by the
* specified <code>Class</code> parameter can be converted to the type
* represented by this <code>Class</code> object via an identity conversion
* or via a widening reference conversion. See <em>The Java Language
* Specification</em>, sections 5.1.1 and 5.1.4 , for details.
*
* #param cls the <code>Class</code> object to be checked
* #return the <code>boolean</code> value indicating whether objects of the
* type <code>cls</code> can be assigned to objects of this class
* #exception NullPointerException if the specified Class parameter is
* null.
* #since JDK1.1
*/
public native boolean isAssignableFrom(Class<?> cls);
It seems strange that in isDeviceEqual(IDevice dev) you are not doing anything with dev. I don't know what mDeviceClass is, but perhaps it should be assigned dev.getClass() somewhere.
When implementing an interface in eclipse, it has a really nice feature that lets you "add unimplemented methods", and it will generate the method stubs for the interface methods.
However, it does not bring along the method documentation from the interface methods, and I was wondering if there was a way to get eclipse to do that.
Here's what I want to happen. Let's say I had an interface like this:
public interface BaseInterface {
/**
* This method takes the given string parameter and returns its integer value.
*
* #param x the string to convert
* #return the integer value of the string
*
* #throws Exception if some error occurs
*/
int method1(String x);
}
Now I create a class called MyClass which implements this interface. What I want to happen is that when I say "Add Unimplemented Methods", I want my code to look like this:
public class MyClass implements BaseInterface {
/**
* This method takes the given string parameter and returns its integer value.
*
* #param x the string to convert
* #return the integer value of the string
*
* #throws Exception if some error occurs
*/
public int method1(String x) {
return 0;
}
}
Yup : these methods are generated using the code templates you wrote.
You'll have to go in "Window/Preferences -> Java/Code style/Code templates"
Then, in the list, select "Comments/overriding methods" and change the content with the one you found in "Comments/methods" :
/**
* ${tags}
*/
You can even think about adding an ${see_to_overridden} to have a direct link to original method. However, notice that a method with no javadoc will automatically inherit its javadoc from its overriden one, so such a template may generate less relevant doc than default behaviour.
You can achieve it by JavaDoc annotation. It is not Eclipse specific and will work in all build/doc generation tools:
/**
* My custom decumentation, and then the original one:
*
* {#inheritDoc}
*/