Java - Comparing classes? - java

How can i compare 2 classes?
The following if statement never passes although class is type of MyClass:
public void(Class class) {
if (class == MyClass.class){
}
}

if (clazz.equals(MyClass.class)) {
}
BTW, class is a reserved word.

To test whether clazz is a (sub) type of MyClass do
MyClass.class.isAssignableFrom(clazz)
From the javadoc for Class.isAssignableFrom
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.
Specifically, this method tests whether the type represented by the specified Class parameter can be converted to the type represented by this Class object via an identity conversion or via a widening reference conversion. See The Java Language Specification, sections 5.1.1 and 5.1.4 , for details.
So
Object.class.isAssignableFrom(String.class)
is true because each String is also an Object but
String.class.isAssignableFrom(Object.class)
is false because not all Objects are Strings.
The name "isAssignableFrom" comes from the fact that,
Class1 x = (Class2) null;
is only legal when
Class1.class.isAssignableFrom(Class2.class)
I.e., we can assign a field or variable with static type Class1 a value that comes from an expression whose static type is Class2.

You can use == or .equals() to compare Class objects.
Example:
class MyClass
{
public static void main (String[] args) throws java.lang.Exception
{
MyClass m = new MyClass();
if (MyClass.class == m.getClass())
{
System.out.println("it worked");
}
}
}
Demo: http://ideone.com/AwbNT

You can use instanceof operator to check if an instance belongs to a specific class or its subclasses.
class MyClass{}
class SubClass extends MyClass{}
public static void main(String args[]) {
SubClass object = new SubClass();
if (object instanceof MyClass) {
System.out.println("It works, too");
}
}

Related

Java passing generic objects

I have different objects(Object A and object B). But some of the objects' fields are same. I can't change the object classes( i mean i cant write a implement/extends condition for them). I want to pass the objects to a method which uses the objects' fields They have same fields. I don't want to overloading. Which design is the most suitable for this?.
A obj1 = new A();
B obj2 = new B();
update(obj1);
update(obj2);
// my function
public <T extends myInterface> void update(T obj)
{
obj.field+=1;
}
public interface myInterface{
int field=0;
}
--------------
public class A{
int field;
.... // smt else
}
--------------
public class B{
int field;
.... // smt else
}
If you have two classes which do not implement a common interface or share a common base class, you can't really pass them to your function.
The fact that they have a common field doesn't matter.
You have 3 workarounds, none of which is really good:
Have your function accept Object type, and check its type (A or B) inside using instanceof. This is ugly and not recommended as any class can be passed inside, and also your code has to check it's type all the time.
Have your function accept Object type, Use reflection to access field with specific name, in this way:
Field field = obj.getClass().getDeclaredField('myfeild');
Object value = field.get(obj);
This is better in that your code doesn't have to check types, but more unsafe. Any class can be passed to your function, and there's some dark magic which relies on static field names. If field name changes, your code breaks.
Perhaps the best - Implement a wrapper for your objects. It will have two constructors, one for class A and one for class B. The wrapper will remember which kind of object resides inside. In its getField function if will have a single if statement. Have your function accept the wrapper type as the argument.
instanceof can be used indentify class of object. Like this:
public <T extends myInterface> void update(Object obj)
{
if ( obj instanceof A )
{
A a = (A)obj;
a.field+=1;
}
if( obj instanceof B )
{
B b = (B)obj;
b.field+=1;
}
}

boolean.isInstance(true) is false?

Problem
The Class Object of a boolean Field does not recognize other booleans as instances.
Code
public class Test {
public boolean b;
public static void main(String[] args) {
System.out.println(Test.class.getFields()[0].getType().isInstance(true));
}
}
Result
false
The method is isInstance(Object) so
x.isInstance(true)
is the same as
x.isInstance(Boolean.TRUE);
and Boolean.class is not a sub-class of boolean.class.
Note: primitives don't have a getClass() method, or any methods for that matter. When you can use it as a Object, it has been boxed.
From documentation of Class#isInstance(Object obj)
... If this Class object represents a primitive type, this method returns false.
Notice that expected argument is always Object, which means it will always be instance of some class (which excludes primitive types).
Even if you pass primitive type here it will be autoboxed to its wrapper class, but such wrapper class is not be same as primitive type represented by Class and in your case returned by getType().

Java casting, overide and polymorphism

In the following example, I reckon it's something about run time polymorphism, but I can't figure out why y.m1(x) prints out A. My understanding is that y.m1() calls the m1()method in class B, because y contains an object of B. Since x is passed to it as a parameter, and it belongs to the class A which is wider than B, won't it lead to a run-time error? Plus how come z.m1(y) prints out A too?
Many thanks in advance!
class A {
public void m1(A a) {
System.out.println("A");
}
}
class B extends A {
public void m1(B b) {
System.out.println("B");
}
}
class D2 {
public static void main(String[] args) {
A x = new A();
A y = new B();
B z = new B();
}
}
B's m1 does not override A's m1 method, as it does not take the same parameter. So B class consist of two overloaded m1 methods, one taking an A object, the other taking a B object.
Only static polymorphism can be used here, that's why you can see this behavior.
The dynamic type of an object (the type used in the new) is it's actual runtime type: it defines the actual methods that are present for an object.
The static type of an object reference (a variable) is a compile-time type: it defines, or rather declares, which methods can be called on the object the variable references.
Because the parameter type of both the dynamic type and the static type are different, we dynamic type doesn't override the method, but overloads it.
If the parameter types would have been the same, the output would be B...

Downcasting objects in Java

class A{
}
public class Demo
{
public static void main(String s[])
{
Object o=(Object) new Demo();
if (((A)(o)) instanceof Object)
{
System.out.println("true");
}
}
}
I am getting Exception while running the class Demo.java:
java.lang.ClassCastException: Demo cannot be cast to A
How to downcast o reference to class A?
You can do that only if Demo extends A, otherwise, you simply cannot cast a class object to any other type.
public class Demo extends A {
Let's start from the beginning: This is terrible code.
That being said:
You are casting Demo to Object (for whatever reason, since in Java everything is Object, no need to cast).
You are then casting o, that you know it's of type Demo, to A (why would this work?).
You are checking if Object o is of type Object (why would this fail?)
Some notes:
o should not be viewed as a reference, it is an instance of Object, as you declared it. Forget how things worked in C.
Consider interfaces and if you want A to be an interface that Demo implements.
You can only cast instances to a class that they already extend.
Downcast example:
public class A {
int variable = 0;
}
public class Demo extends A{
}
public void testDowncast(){
Demo myClass = new Demo();
myClass.variable = 2;
A morphingTime = myClass;
System.out.println("And now Power Ranger Demo has turned into Mighty A:");
System.out.println("I am: "+morphingTime.getClass() + " and my variable is: " + morphingTime.variable);
}
The answer by R J is right
you can do that only if Demo extends A
For your information, you do not need to type cast any object while assigning to Object
Object o= new Demo();
and every object will always be instanceof Object i.e. your condition instanceof Object for class objects will always be true
And why are you trying to do the things this way, ((A)(o)) without checking the type with instanceof rather it should be,
if (o instanceof A)
First of all, you'r getting 'ClassCastException' because your actual object 'o' is of type class 'Demo' and classes 'Demo' and 'A' are not in the same inheritance tree. You didn't get compile error only because you have cast your object to class 'Object' (since 'A' and 'Object' are in the same inheritance tree). To resolve you situation you should change you code such that make both of them ('Demo and 'A') to be part of the same inheritance tree. For example you can extend Demo from A. Then, check the object 'o' without cast like this
if (o instanceof A) {
// now cast to 'A'
// and invoke any accessible method (or etc.) that class A provides
((A)o).doSomthingMathod();
}
You should simply rewrite your code as
Object o=new Demo();
if (o instanceof A)
{
System.out.println("true");
}
and then see what changes if Demo extends A
First thing u do not need to cast your Demo instance to object becuase without casting you can assign the Demo reference to Object class because Object is super class of all java classes.
public class Demo extends com.A {
}
Downcasting is the act of casting a reference of a base class to one of its derived classes.
For example :
public class Parent{}
public class Child extends Parent{}
public static void main(String args[]){
Parent parent = new Child(); // Parent is parent class of Child, parent variable holding value of type Child
Child child = (Child)parent; // This is possible since parent object is currently holding value of Child class
}
You can refer this question to get the answer.

get the type of String object - java

I'm trying to find the hierarchy of the Object - "String" using the below method.
public class test{
public static void main(String[] args){
String x = "Test";
System.out.println(x.getClass().getClass());
}
}
The first x.getclass() return
Output:
class java.lang.String
then -System.out.println(x.getClass().getClass());
Output:
class java.lang.Class
and anything after that yields the same result
System.out.println(x.getClass().getClass().getClass().getClass());
Shouldn't it at some point lead to - java.lang.Object??
Result is correct since you are calling getClass() on Class instance. To get parent class you should call getSuperclass() from Class instance that represents subclass type.
String x = "Test";
System.out.println(x.getClass().getSuperclass());
Output
class java.lang.Object
x.getClass().getClass() will always return the class object representing java.lang.Class for any non-null value x.
That's because x.getClass() can only return a Class object and you're asking that class object what type it is (obviously: Class).
What you seem to want to try is not x.getClass().getClass() but x.getClass().getSuperClass(). Repeating that last part will eventually lead to java.lang.Object, as you expected (and, if repeated one more time, to null).

Categories

Resources