Why A.class is null in run time? - java

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.

Related

Is it possible to override a method comment but not the method?

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?

Why reflective Members must be copied before propagation?

If you look into the source code of getting reflective objects of fields, methods or constructors, their copies are returned. Lets take getting field as example:
/**
* Returns an array of {#code Field} objects reflecting all the fields
* declared by the class or interface represented by this
* {#code Class} object. This includes public, protected, default
* (package) access, and private fields, but excludes inherited fields.
*
* <p> If this {#code Class} object represents a class or interface with no
* declared fields, then this method returns an array of length 0.
*
* <p> If this {#code Class} object represents an array type, a primitive
* type, or void, then this method returns an array of length 0.
*
* <p> The elements in the returned array are not sorted and are not in any
* particular order.
*
* #return the array of {#code Field} objects representing all the
* declared fields of this class
* #throws SecurityException
* If a security manager, <i>s</i>, is present and any of the
* following conditions is met:
*
* <ul>
*
* <li> the caller's class loader is not the same as the
* class loader of this class and invocation of
* {#link SecurityManager#checkPermission
* s.checkPermission} method with
* {#code RuntimePermission("accessDeclaredMembers")}
* denies access to the declared fields within this class
*
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of {#link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the package
* of this class
*
* </ul>
*
* #since 1.1
* #jls 8.2 Class Members
* #jls 8.3 Field Declarations
*/
#CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyFields(privateGetDeclaredFields(false));
}
And
// Returns an array of "root" fields. These Field objects must NOT
// be propagated to the outside world, but must instead be copied
// via ReflectionFactory.copyField.
private Field[] privateGetDeclaredFields(boolean publicOnly) {
Field[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;
if (res != null) return res;
}
// No cached value available; request value from VM
res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicFields = res;
} else {
rd.declaredFields = res;
}
}
return res;
}
And
private static Field[] copyFields(Field[] arg) {
Field[] out = new Field[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyField(arg[i]);
}
return out;
}
And in jdk.internal.reflect.ReflectionFactory
/** Makes a copy of the passed field. The returned field is a
"child" of the passed one; see the comments in Field.java for
details. */
public Field copyField(Field arg) {
return langReflectAccess().copyField(arg);
}
And in java.lang.reflect.Field
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private Field root;
And in java.lang.reflect.ReflectAccess (implementation of jdk
public Field copyField(Field arg) {
return arg.copy();
}
And finally back to java.lang.reflect.Field
/**
* Package-private routine (exposed to java.lang.Class via
* ReflectAccess) which returns a copy of this Field. The copy's
* "root" field points to this Field.
*/
Field copy() {
// This routine enables sharing of FieldAccessor objects
// among Field objects which refer to the same underlying
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
if (this.root != null)
throw new IllegalArgumentException("Can not copy a non-root Field");
Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
res.root = this;
// Might as well eagerly propagate this if already present
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
return res;
}
But why? Cannot we just simply access the root Field object and mess with it?
I'm not an expert with reflection, so there might be other reasons. But a Field is mutable (setAccessible()). Not returning a copy would mean that making it accessible in one part of the code would make it accessible everywhere, even in other code relying on the field not being accessible, or not allowed tomake it accessible.

Why does the MethodMatcher interface in Spring Framework takes a targetClass as argument, where Pointcut already defines a Classfilter?

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.

How to write Javadoc for a getInstance method?

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() {

Suspicious call to java.util.Collection.contains

I am getting the following warning from my NetBeans IDE.
Suspicious call to java.util.Collection.contains
Expected type T, actual type Object
May I know what does that means?
This doesn't make sense to me. Both List and Collection class's contains method, are using Object as their method parameter.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
*
* #author yan-cheng.cheok
*/
public abstract class AbstractCollection<T> implements Collection<T> {
protected List<T> list = new ArrayList<T>();
public boolean contains(Object o) {
// Suspicious call to java.util.Collection.contains
// Expected type T, actual type Object
return list.contains(o);
}
Code snippet from Collection class
/**
* Returns <tt>true</tt> if this collection contains the specified element.
* More formally, returns <tt>true</tt> if and only if this collection
* contains at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* #param o element whose presence in this collection is to be tested
* #return <tt>true</tt> if this collection contains the specified
* element
* #throws ClassCastException if the type of the specified element
* is incompatible with this collection (optional)
* #throws NullPointerException if the specified element is null and this
* collection does not permit null elements (optional)
*/
boolean contains(Object o);
Code snippet from List class
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* #param o element whose presence in this list is to be tested
* #return <tt>true</tt> if this list contains the specified element
* #throws ClassCastException if the type of the specified element
* is incompatible with this list (optional)
* #throws NullPointerException if the specified element is null and this
* list does not permit null elements (optional)
*/
boolean contains(Object o);
In the call to list.contains you are comparing an object to a type T. Casting o to type T should resolve your warning.
Calling the contains method with an Object instead of the generic type may be a programming error. Since the code is still valid the compiler will only show a warning.
An example why this warning is necessary:
List<Long> l = new ArrayList<Long>();
l.add(1l);
l.contains(1);
The code is valid but would always return false. An error that is normally hidden by contains accepting object instead of a generic type, so the compiler is limited to warnings.
Since there are valid use cases for passing an object, you should be able to use a #SuppressWarnings() annotation to hide this warning (only do this if you know what you are doing).

Categories