Why ReflectionChild.class.isInstance(Class.class) is not true?
As we know in reflection Class.class.isInstance(Class.class) is true. Now see on below code snip.
ReflectionChild ch = new ReflectionChild(); //Take random class
if(ch.getClass()==ReflectionChild.class){
System.out.println("ch.getClass()==ReflectionChild.class");
}
System.out.println(ReflectionChild.class.getClass());
System.out.println(Class.class);
if(ReflectionChild.class.getClass()==Class.class){
System.out.println("ReflectionChild.class.getClass()==Class.class");
//System.exit(0);
}
if(ReflectionChild.class.isInstance(Class.class)){
System.out.println("true");
//System.exit(0);
}else{
System.out.println("false");
}
The output is :-
ch.getClass()==ReflectionChild.class // 1st SYSOUT
class java.lang.Class // 2nd SYSOUT
class java.lang.Class // 3rd SYSOUT
ReflectionChild.class.getClass()==Class.class //4th SYSOUT
false // 5th SYSOUT
According to above 1st four SYSOUT's the line ReflectionChild.class.isInstance(Class.class) should be true. But for me it is false as output .
Can any one explain?
Class.class is an instance of Class, not ReflectionChild.
Therefore, isInstance() returns false.
Because a Class instance is not an instance of of type ReflectionChild.
From the javadoc
Specifically, if this Class object represents a declared class, this
method returns true if the specified Object argument is an instance of
the represented class (or of any of its subclasses); it returns false
otherwise.
The argument you've provided is of type Class which is not an instance of the type ReflectionChild represented by the Class instance returned by the class literal expression ReflectionChild.class.
From the Javadocs of Class#isInstance(Object):
Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.
So the object passed as an argument to the method must be an instance of the class represented by the object on which the method is called, not the other way around: the expression that should return true is the following:
if(Class.class.isInstance(ReflectionChild.class)){
Related
I am dealing with some past exam papers and here I am not sure of the output. I think I am not clear about extends and super.
public class Superclass{
public boolean aVariable;
public void aMethod(){
aVariable = true;
}
}
class Subclass extends Superclass {
public boolean aVariable;
public void aMethod() {
aVariable = false;
super.aMethod();
System.out.println(aVariable);
System.out.println(super.aVariable);
}
}
I think that the second output would be true since it would refer to the super class and it is an object. However, I am not sure of the first output. Would it be just a value and print false or it is also an object?
The output will be:
false
true
Because in your Subclass aVariable is false by default (so assignation aVariable = false; is needless). Read more about Primitive Data Types default values.
And in Superclass you initialize aVariable as true by invoking the superclass' method using the keyword super: super.aMethod();. Read more about Accessing Superclass Members.
Take a look on demo.
Since they're both scoped to their own class block, having them with the same name doesn't matter. As it looks like now, you set aVariable to false, the call to the super doesn't change that, except for creating another variable (new reference) with the same name and sets it to true. So the expected output would be
false
true
Output will be:
false
true
super.aMethod() will execute making aVariable = true of SuperClass
aVariable of SubClass will remain false.
I conducted scientific experiment (copy-pasted and ran) and it prints
false
true
More here:
If you overwrite a field in a subclass of a class, the subclass has two fields with the same name(and different type)?
Suppose I have a custom class, say Test.
Test test = new Test(); // test is the reference.
Now when I print the value of test, it returns the hashcode .
Now consider,
Integer i = new Integer(10);
When I print the value of i, it returns 10.
Can someone help me to understand what exactly is the difference here? I believe both are object references, but for wrapper class reference, it returns the value of the object it is pointing to.
When you create a new class, it inherits the method toString() from Object. Integer class overrides that method to return the inner value.
When printing, there is an implicit call to toString() method.
By default (in for your Test class) it uses the one inside Object class. For Integer, it convert the Integer to a String in 10-base.
Your Test class is using Object class's toString() method which prints hashCode. But for Integer class, toString method is overrided. You can see Integer.java here
user defined reference is an object,if you print that object means you may get some hash code because every class extends Object class,so your also have the property (method) tostring().
Wrapper class wraps its respective primitive data type
Integer i = new Integer(10);
and
i=10;
both same in value.
When you call System.out.println(Object) (or, more generally, PrintStream.println(Object)):
This method calls at first String.valueOf(x)
String.valueOf(Object) returns:
if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
Neither of your objects are null, so the toString() method of the instances is called.
In the case of Integer:
The value is converted to signed decimal representation and returned as a string
In the case of Test, unless you've explicitly overridden it (or a superclass has overridden it), you will call Object.toString():
[T]his method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
If this isn't the desired behaviour, override toString() in Test:
class Test {
#Override public String toString() {
// ... Your implementation.
}
}
Whenever you print the object Java will invoke the toString() method. The default implementation of toString() available in Object Class. Object is the base class for the all the Object in java.
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
It will print the class Name with full package path # and HashCode of the object.
The test class doesn't override the toString() method. But all the wrapper class in java override the toString().so when You invoke the Integer method it invoke the toString() implemented in Integer class.
In my GameObject class I have the following method to check if the GameObject would be colliding with another object if it moved to the specified position:
public boolean collisionAt(Vector2d position, Class<? extends GameObject>... exclusions) {
if (getBounds() == null)
return false;
Rectangle newBounds = getBounds().clone();
newBounds.setPosition(position);
// Check collisions
for (GameObject object : new ArrayList<>(gameObjects)) {
if (object.getBounds() != null && newBounds.intersects(object.getBounds()) && object != this) {
boolean b = true;
for (Class<? extends GameObject> exclusion : exclusions) {
if (object.getClass().isInstance(exclusion))
b = false;
}
if (b)
return true;
}
}
return false;
}
I want to allow the program to define exclusions, for example if I don't want this method to return true if it collides with a Spell. But for some reason the Class.isInstance() line always returns false. I even tried this:
System.out.println(Spell.class.isInstance(Spell.class));
and the console outputs false! What's going on here?
The isInstance tests if the given object is an instance of the Class, not if the given Class is a subclass of the Class.
You have your invocation backwards. You need to test if the gameObject is an instance of one of the exclusion classes.
if (exclusion.isInstance(gameObject))
From official Javadocs
public boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.
You need to pass in the object of class rather than the class itself.
Example
SomeClass object = new SomeClass();
System.out.println(SomeClass.class.isInstance(object));
You need to pass in an instance of the class in question rather than a class literal. E.g.
Spell spell = new Spell();
System.out.println(Spell.class.isInstance(spell));
isInstance determines if the specified Object is assignment-compatible with the object represented by this Class. You're passing it a class when it expects an object.
The opposite should work:
Spell.class.isInstance(spell)
Why is second SOP showing output as true here, I was hoping it would display false like first SOP ?
public class reflect1 {
public static void main(String[] args) {
Reflect1A obj1 = new Reflect1A();
Reflect1A obj2 = new Reflect1A();
System.out.println(obj1 == obj2);
Class c1 = obj1.getClass();
Class c2 = obj2.getClass();
System.out.println(c1 == c2);
}
}
class Reflect1A {
}
From the Java Language Specification
The method getClass returns the Class object that represents the class of the object.
A Class object exists for each reference type. It can be used, for
example, to discover the fully qualified name of a class, its members,
its immediate superclass, and any interfaces that it implements.
Since both your objects are of type Reflect1A, they both return the same Class object.
You would get the same object by doing
Class<?> clazz = Class.forName("com.example.Reflect1A")
System.out.println(c1 == clazz); // true
(though this is not necessarily required by all classloaders.)
The values of obj1 and obj2 refer to different objects - when you use == in Java and both operands are references, the result is to compare whether those references refer to the exact same object. In this case you've got two different objects, so the references are not the same.
However, they're both of the same class, so that's why c1 == c2 is true.
The first line prints false because it is a different instance of the same class.
The second line prints true because it is the same class type. There is a obscure gotcha here to be aware of, if you're in a multiple classloader environment, e.g. an application server like JBoss, or OSGI etc, it is possible for two class instances to not be equal
An object is equal (==) only to itself. So clearly both getClass() statements are returning the same Class object
Because obj1 and obj2 are different instances (first check is false) of the same type (class - second check is true).
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#getClass%28%29
why did you expect to return false?
The operator == compares the references in which the objects are created by default
Obj1 and Obj2 are of same type class Reflect1. For these objects are equal only when compared like this obj1.equal(obj2).
While the class type of obj1 and obj2 are the same == operation will be true.
I have a class called ScalarObject and a class called Variable that inherits from ScalarObject. I defined "equals" on ScalarObject that always returns false, and on Variable that returns true when the strings representing them are equal.
The following code:
ScalarObject a1 = new Variable("a");
ScalarObject a2 = new Variable("a");
System.out.println(a1.equals(a2));
return false. The following code:
Variable a1 = new Variable("a");
Variable a2 = new Variable("a");
System.out.println(a1.equals(a2));
returns true. The following code:
ScalarObject a1 = new Variable("a");
ScalarObject a2 = new Variable("a");
System.out.println(((Variable) a1).equals(((Variable) a2)));
also returns true. The problem is that I have other classes that also derive from ScalarObject. I have parts of my program objects that are declared of type ScalarObject but could be a member of any class that derives from it, so casting a ScalarObject object to a derived type won't work. For example, in one part of my program I have:
protected void neighbor_simplify(LinkedList<ScalarObject> L, char op) {
...
if(n1 instanceof Variable && n2 instanceof Variable) {
System.out.println(((Variable) n1).getSymbol());
System.out.println(((Variable) n2).getSymbol());
}
if(n1.equals(n2)) { // x+x=2*x
System.out.println("B ");
and the program prints out "x" twice but does not print "B". The variables n1 and n2 come from the linked list "L". I suspect that the program is calling "ScalarObject.equals()" (which always returns false) and not "Variable.equals()". The problem with casting n1 and n2 to type Variable is that n1 and n2 could be instances of some other class that is also derived from ScalarObject. How do I get the program to call a member from a derived class not a base class even when it is declared as a base class?
I am using NetBeans 6.9.1 on Windows Vista.
Searching on the web has taken me to http://wiki.answers.com/Q/Can_a_base_class_access_members_of_a_derived_class which states that in Java a base class can access members of a derived class when #Override notation is used. However, when I added #Override to Variable.equals(), I got an error stating that the method does not override a method from a supertype, probably because the siguatures are different. ScalarObject.equals() takes an argument of type ScalarObject and Variable.equals() takes an argument of type Variable.
the equals method must be defined as public Object equals(Object obj) in all classes in order for them to override correctly (hint, listen to the #Override annotation compilation error).
You should be very careful with the difference between overriding and overloading.
If the signatures of the equals methods in the base and the derived class match (which should be the case, see jtahlborn's answer), you have overriding. This uses dynamic binding: the correct equals method is determined at runtime, so
ScalarObject a1 = new Variable("a");
a1.equals(...);
calls the equals of Variable, since the type of a1 is determined as Variable at runtime.
If the signatures of the equals methods don't match (equals(ScalarObject so) vs equals(Variable v)), you have overloading. This uses static binding. That is, even if you do
Variable a1 = new Variable("a");
ScalarObject a2 = new Variable("a");
a1.equals(a2);
the last line will use ScalarObject.equals(ScalarObject so), because the compiler cannot infer that a2 is of type Variable.
Long story short: always use overriding for your equals method, that is, use public boolean equals(Object o).
What you want to do here is make Variable's equals method override ScalarObject.equals by changing it's signature to accept a ScalarObject and then use the instanceof operator to take different actions based on the actual type of the passed in object.