New to Java coming from C++/Python and I found this in code today (not exactly this but similar [cant share code]):
File dir = new File("/home");
File[] files= dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
When looking at source of listFiles, filter is passed this representative of the reference to dir. But in its implementation its not used at all, only name is. When it comes implementing interfaces in Java, is this common place to have an abstract method with "potentially used" parameters, but they aren't required to be used? In C++/Python my linters would be going bonkers saying parameters are unused and can be removed.
Why not have multiple methods then for the interface?
#FunctionalInterface
public interface FilenameFilter {
/**
* Tests if a specified file should be included in a file list.
*
* #param dir the directory in which the file was found.
* #param name the name of the file.
* #return {#code true} if and only if the name should be
* included in the file list; {#code false} otherwise.
*/
boolean accept(File dir, String name);
/**
* Tests if a specified file should be included in a file list.
*
* #param name the name of the file.
* #return {#code true} if and only if the name should be
* included in the file list; {#code false} otherwise.
*/
boolean accept(String name);
}
Why not have multiple methods then for the interface?
FilenameFilter is a functional interace and in functional interface you can't have more than 1 abstract method. Had it not been a functional interface, you could have overloaded abstract method, but then you wouldn't be able to use lambda expression in your code.
Secondly, the fact that you are not using one parameter is an implementation detail! There might be another implementation in code somewhere else that would use it.
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?
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.
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() {
java.util.Map.Entry as I know is a public static interface in java.util package that
returns collection view of a map but as far now I am confused with the static interface
and as it is Map.Entry is it an inner interface if so how do we have inner static interfaces in java
The definition of Entry happens to live inside the definition of Map (allowed by java). Being static means you don't need an instance of Map to refer to an Entry.
It's easiest to show how to use Map.Entry by an example. Here's how you can iterate over a map
Map<Integer, String> map = new HashMap<Integer, String>();
for (Map.Entry<Integer, String> entry : map.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
// do something with key and/or value etc
// you may also alter the entry's value inside this loop via entry.setValue()
}
There isn't really anything to be confused about.
Yes, Java allows interfaces to be members of classes or other interfaces.
No, that does not mean anything special. It changes absolutely nothing about how you can use such an interface or what you can do with it.
It only changes the name of that interface and creates a strong conceptual link between it and its enclosing type. In this case, a Map.Entry represents an entry of a Map. The designers of the API apparently felt that it made sense to stress this connection by making it a member type.
Example:
public class Outer {
public interface Bar {
Bar get();
}
}
Bar is a nested interface. Nested interfaces are static by default, so you could as well write:
public class Outer {
public static interface Bar {
Bar get();
}
}
Now, what static in this context means is that the interface is a static member, i.e. a member of the class.
You can do this with classes as well:
public class Tree {
private static class Node {
}
}
Here, Node is even private, meaning it's only visible within Tree. So, what's the benefit of this? Why not make Node a public class? Because of better encapsulation. First, the Node is an implementation detail of the Tree, so you don't want it to be visible. Second, if you expose Node via a public API, some client (programmer) could use it in his code. Now, he has a hard dependency on this class. If at some point you want to change the representation of you Tree, and you change/remove the Node class, the client code's may break. And last but not least, your public API becomes smaller, which is also desirable.
So, when to use static member classes/interfaces? Mostly, if you build some sort of Composite object (like a Tree, or a Linked List) or when the class only makes sense in the context of the outer class.
Java allows nested interfaces. You can nest them into classes or interfaces. For instance, Map.Entry is a nested interface defined in the Map interface.
Map implementations (TreeMap, HashMap) provide private implementations of Map.Entry, which are not visible outside the class.
Bohemian's answer addresses how to use Map.Entry.
Yes, it's an inner interface of the Map interface.
/**
* A map entry (key-value pair). The <tt>Map.entrySet</tt> method returns
* a collection-view of the map, whose elements are of this class. The
* <i>only</i> way to obtain a reference to a map entry is from the
* iterator of this collection-view. These <tt>Map.Entry</tt> objects are
* valid <i>only</i> for the duration of the iteration; more formally,
* the behavior of a map entry is undefined if the backing map has been
* modified after the entry was returned by the iterator, except through
* the <tt>setValue</tt> operation on the map entry.
*
* #see Map#entrySet()
* #since 1.2
*/
interface Entry<K,V> {
/**
* Returns the key corresponding to this entry.
*
* #return the key corresponding to this entry
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
K getKey();
/**
* Returns the value corresponding to this entry. If the mapping
* has been removed from the backing map (by the iterator's
* <tt>remove</tt> operation), the results of this call are undefined.
*
* #return the value corresponding to this entry
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V getValue();
/**
* Replaces the value corresponding to this entry with the specified
* value (optional operation). (Writes through to the map.) The
* behavior of this call is undefined if the mapping has already been
* removed from the map (by the iterator's <tt>remove</tt> operation).
*
* #param value new value to be stored in this entry
* #return old value corresponding to the entry
* #throws UnsupportedOperationException if the <tt>put</tt> operation
* is not supported by the backing map
* #throws ClassCastException if the class of the specified value
* prevents it from being stored in the backing map
* #throws NullPointerException if the backing map does not permit
* null values, and the specified value is null
* #throws IllegalArgumentException if some property of this value
* prevents it from being stored in the backing map
* #throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V setValue(V value);
/**
* Compares the specified object with this entry for equality.
* Returns <tt>true</tt> if the given object is also a map entry and
* the two entries represent the same mapping. More formally, two
* entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
* if<pre>
* (e1.getKey()==null ?
* e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
* (e1.getValue()==null ?
* e2.getValue()==null : e1.getValue().equals(e2.getValue()))
* </pre>
* This ensures that the <tt>equals</tt> method works properly across
* different implementations of the <tt>Map.Entry</tt> interface.
*
* #param o object to be compared for equality with this map entry
* #return <tt>true</tt> if the specified object is equal to this map
* entry
*/
boolean equals(Object o);
/**
* Returns the hash code value for this map entry. The hash code
* of a map entry <tt>e</tt> is defined to be: <pre>
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
* </pre>
* This ensures that <tt>e1.equals(e2)</tt> implies that
* <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
* <tt>e1</tt> and <tt>e2</tt>, as required by the general
* contract of <tt>Object.hashCode</tt>.
*
* #return the hash code value for this map entry
* #see Object#hashCode()
* #see Object#equals(Object)
* #see #equals(Object)
*/
int hashCode();
}
For more information about interfaces, see the Interfaces tutorial and this Static Nested Interfaces article.
Inner interfaces are implicitly public and static.
You can have inner interfaces as follows :
1. interface A {
.....
.....
interface B {
....
....
}
}
2. class A {
....
....
interface B {
....
....
}
}
You can access the above inner interface(B) by A.B where A is a class or an interface according to the above two cases.
For example,
class x implements A.B
{
....
....
}
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}
*/