Built in function for Different Super class objects - java

I want to compare the super classes of two different objects.If it is same then it should ask for another opponnet. Unless it selects the type that is diffenret. I have the following code for it. But it always returns true.
boolean equal(Characters C)
{
return (C.getClass().getSuperclass()== Char.getClass().getSuperclass());
}

we can compare the objects of different classes by calling O1.getClass()==O2.getClass() function of object if the object has same class it return true else false. In case of inheritance if we want to know that the two objects are belonging to same superclass or different then we calling O1.getClass().getSuperClass()==O2.getClass().getSuperClass() to campare.

Related

Could someone explain me the .getClass() method in java

I am currently taking a java class in university. This is my first programming class and I've stumbled on something that I just cannot understand. As i learned, there are two ways of comparing variables. The first is using the ==, !=, <, > , =< , >= signs for PRIMITIVE variables such as int,double,etc. and the second way is to use the .equals() method for reference type. Now here is my question:
When I use the .getClass() method, I can compare two classes with the .equals() method and the == / != method. Since I can use the ==/!= signs, I'd suppose that the .getClass() method which returns the class of an object must return a primitive type. But searching on google the only thing I found out about this method in the java API is that it returns the class of an object. It doesn't tell me the variable type it returns. How exactly does this method work. What does it return? I tried to ask my teacher but she didn't know. Thank you!
You first need to know how == and != compare the two operands. The reason why == and != cannot be used to compare reference types is that they actually compare the memory addresses of the two reference type variables.
So if I have two strings:
String x = "Hello";
String y = x;
Since x and y share the same memory address after the second line is executed, x == y evaluates to true.
The same goes for the getClass() method. The getClass() method returns the class of the object as a Class<T> object. The question is, why this evaluates to true:
x.getClass() == y.getClass()
The answer is simple. Because x and y are both of type String. So calling getClass will return the same instance. This means the two returned the objects share the same memory address.
"But when I compare strings with the same characters with the == operator, it evaluates to false!" you shouted.
This is because the strings are located at different memory addresses. But the classes that getClass will return is always at the same memory address if the class that they represent is the same. This is due to the way ClassLoader works. But I'm not an expert that.
You just need to know that the objects returned by getClass is at the same memory address if the classes they represent are the same.
The comparators == and != compare equality in the way of identity. So how this works for primitives is obvious. However it can also be used to compare objects. However most often this does not work as expected. There are some exceptions:
Strings are stored as literals, therefore if you define two instances of String containing the same value, they use the same literal. Think of this like both instances pointing to the same memory location.
Enums are basically a collection of constants, therefore an enum value is either the same instance or it is not. It cannot be that the enum has the same value but is another instance.
The same is true for Class objects, which is what you get when calling getClass(). A Class object is created by the ClassLoader the first time it is the *.class file is loaded. On subsequent calls the same Class object is used. Therefore Class objects may be compared with == and !=. However beware that if A.class is loaded by two different ClassLoaders, the class objects that you get returned from them are not of the same instance.
getClass() returns an instance (object) of the Class class. Since each Java class has a single instance of the Class class, if two objects belong to the same class, getClass() for those two objects will return the same isntance and therefore you can use == for comparing them, since == when applied to reference types determines if the two references refer to the same instance.
The .getClass method will just return the class of the object. When you declare a new instance of an object, it will be referring to a class. There can only be one class per jvm but multiple object referring to it. So when you get the class of two objects, they might be referring to the same class!
polymorphism is one of the most important feature for java. for example:
//this shows one use of getclass method.
public class Main {
public static void main(String[] args) {
Main m = new Main();
Animal animal = new Animal();
Human human = new Human();
m.dosomething(animal);//print animal
m.dosomething(human);//print human
}
private void dosomething(Animal an){
System.out.println(an.getClass().toString());
}
}
class Human extends Animal{
private void dance(){
}
}
class Animal{
private void eat(){
}
}

Java reflection check if passed Objects are same type

I have a class with compare method. The method takes two objects as arguments.
With java reflection I was able to get all the private and protected field and with some fancy stuff check their return types and do what I want to do with them.
This is good for me personaly. I know what I want to do so I just compare two objects of same type and thats all.
BUT ... this is used by many people ...and they sometimes are unable to read a Javadocs and comments and other stuff I put there so I have to check if they are passing object of same type. For example you have :
Car a, Car b , Truck a, Truck b ... and so on..
I need to check if the two passed arguments are actually the same type for comparing (Car with car , Truck with truck..)
So ... I dont know the stuff.. Should I use the reflection for listing the size of all fields and then check if all the fields have the same name ?
Or is there a better solution ? Becouse writing something like if the fieldsOfA.size is same as fieldOfB.size ... and then for loop for this if they are same to check the names looks kinda weird..
Also another problem.
Those objects have lists of some other object - for example Car has a list of Wheels..
And you are comparing the wheels with other car.
They have like Wheel 1 , Wheel 2 , Wheel 3, Wheel 4 in list..
and the second car has Wheel1, Wheel 2, WHeel 4 and WHeel 3 ..
So the objects are same , but just have switched positions..is there a way to prevent this ? I have a tracking code that stores every difference in those objects.. So if they have different positions it gives me two changes.. Wheel 3 is different from other car and wheel 4 is different on other car..
But they are still the same ...
I don't know how to solve this with reflection ... Any Ideas ?
To compare classes just use if(object1.getClass() == object2.getClass())
To be fair, it's either a.getClass().isInstance(b) or a.getClass().isAssignableFrom(b) but I always forget which one is which.
boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class.
And
boolean isAssignableFrom(Class<?> cls)
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.
You probably need the first.
You can use the instanceof operator.
For example:
public boolean isCar(Vehicle x) {
if (x instanceOf Car) {
return true;
} else {
return false;
}
// note: you can also just do "return x instanceof Car"
}
This sounds like you're attempting to write a General Purpose Equals Method. Just in case you are: be aware that this will fail in the general case, because object equality does not necessarily mean all fields are equal, or even that all public fields are equal. It is possible for two Java objects to be intentionally equal even if some fields are different. Equality between two instances of a given class is defined by the programmer designing that class, and anyone subclassing it implicitly abides by their equality contract.
Given that, it's generally a bad idea to attempt to dig out an object's superclass' private fields. A much better idea: super.equals().
So, suppose you write a class Truck that extends Vehicle, and Truck defines two private fields, maxLoad and hasTrailerHitch. You define whether two Trucks are equal; suppose you need both these fields to be equal. In reality, you probably also want them to satisfy whatever equality conditions Vehicle defines. So your equals is likely to look something like this:
#Override
public boolean equals(Object obj) {
// check for type
if (!(obj instanceof Truck)) return false;
// check private fields
Truck other = (Truck)obj;
if (this.maxLoad != other.maxLoad ||
this.hasTrailerHitch != other.hasTrailerHitch) return false;
// check for Vehicle equality
if (!super.equals(obj)) return false;
// everything checks out!
return true;
}
I wrote this a bit less compactly than I would in practice, for display purposes. The order of the checks ideally doesn't matter; I put the superclass check last, since I know two private field comparisons runs really fast, but I don't necessarily know what's involved in checking Vehicles.
Notice how the instanceof works. If someone (including you!) writes a subclass of Truck later, the instanceof will be true, and so if they do the same thing you do and call super.equals(obj), your Truck.equals will check those two private fields, as it should. If, instead of an instanceof check, you had been more strict, say:
if (obj.getClass().getName().equals("my.pkg.Truck")) // ...
then subclasses of Truck would not get these private fields checked properly. Two instances of, say, DumpTruck would never be equals - probably not what you intend.

Check if an object is of the same class as this?

I have a base class for multiple data object types in Java. I want to create an equals method in the base class, that works directly when inherited.
Equality is determined by the two objects
belonging to subclasses of the base class. This is easily achievable using
if (!(anObject instanceof BaseClass))
return false;
having the same ID. The ID field is defined by the base class so we can here test that.
if (this.id != ((BaseClass) anObject).id)
return false;
belonging to the same class. This is where I have the problem. Two objects may be of different types (and so be in different lists), but have the same ID. I have to be able to distinguish them. How can I do this?
Use
this.getClass() == anotherObject.getClass()
instead of instanceof. This will return true only if the two object belong to the same class (it's safe to check if class objects are equal by reference). And after that you may compare the id.
You should read this article for problems when implementing equals.
To make it short: use this.getClass()==other.getClass() instead of instanceof, because otherwise the equals() relationship will not be transitive (superInstance.equals(subInstance) will be true, but subInstance.equals(superInstance) will be false).
If I understand you question correctly, you need a way to differentiate two objects of same Class with same id. If so, for this you may use toString() which gives unique representation of objects unless they are string objects. Of course, you must not have overridden toString() in your base class.
example:You can use this, only for the third case that you mentioned.
if (this.toString()!= anObject.toString())
return false;
You can do that with Class.isInstance() method. In your base class, do this.
public static boolean isAnInstance(Object obj)
{
return BaseClass.class.isInstance(obj);
}
Then you can check
if (BaseClass.isAnInstance(object))
{
// Class of object is 'BaseClass' or
// it extends the 'BaseClass'
}
Hope this helps.
The best practice to know objects equality is to override hashcode() and equals() if you maitain objects in a collection
you can refer Why do we have to override the equals() method in Java?

Implementing .equals(Die aDie) method and static variables

I am creating the method .equals(Die aDie) in my program. Do I compare every instance variable including static ones?
boolean equals(Die aDie)
is wrong, classes will call the equals(Object) method and ignore your equals(Die). Also implement the int hashCode() method using the same fields that equals(Object) uses.
#Override public boolean equals(Object aDie){
if(aDie == null || aDie.getClass() != Die.class)return false;
if(aDie == this)return true;
Die other = (Die)aDie;
...
}
#Override public int hashCode(){
...
}
You can ignore static fields since they are the same for every Die.
Static variables, by definition, are not instance variables, and will therefore always be equal across all instances of the same class.
Definitely not the static ones.
Whether you compare all the instance variables depends on what determines the "identity" of your objects, i.e. when do you consider them equal? This can only be decided in the context of your particular application - we'd need more information.
For example, if you had a class representing books, you might only compare the ISBN number to determine whether two books are the same book, if you just wanted to store metadata about them (title, author). If you merged two such databases, you'd want to eliminate duplicate records.
BUT, if you were implementing a library catalogue of actual physical books, each individual copy is important and different, so you might compare ISBN and copy number. If you merged two libraries, you'd expect to be able to detect duplicate copies.
You would compare every instance variable.
Static variables are guaranteed to be equal, as they are class-specific, not instance-specific, so you don't have to worry about comparing them.
It would make no sense, both because with equals() you compare instances and because, well, they are static: what would you compare them to, themselves?
It is useless to compare static data, as it is shared among all instances of your Die class. But you can compare the various fields by accessing them directly (see example below). Note that if your Die object has complex fields (such as instances of Map, Set, etc), you should also call the equals methods on those objects (again, see example below).
If you want to provide an equals () method, you should override the one provided in the Object class (equals (Object anOtherObject), rather than overloading it, or at least make sure you also override equals (Object anOtherObject) to make sure that it returns the correct value too (the default implementation only checks if it's the same instance). And in your method you should then check if anOtherObject is an instance of Die.
Here's an example, assuming that your Die class has 3 fields: String name, int value and Map<Integer> complexField:
public boolean equals (Object anOtherObject) {
if (anOtherObject == this) {
return true;
}
if (!anOtherObject instanceof Die) {
return false;
}
Die otherDie = (Die) anOtherObject;
if (this.value != otherDie.value ||
!this.name.equals (otherDie.name) ||
!this.complexField.equals (otherDie.complexField)) {
return false;
}
return true;
}
Josh Bloch's "Effective Java" has a very details section on how to correctly implement equals. You should definitely read it.
When a variable is declared with the keyword “static”, its called a “class variable”. All instances share the same copy of the variable (always be equal across all instances of the same class). A class variable can be accessed directly with the class, without the need to create a instance.

How to CompareTo two Object without known about their real type

I have to implement a one linked list but it should put object in appropriate position.
Everything was OK when I use it in conjunction with specific class, but when I tried make it universal and argument of method insert was Object some problem appeared.
When I want to input Object in right position I should use CompareTo method, but there isn't method in Object class!
The problem is how to compare two object elements without known about their real types.
Maybe I should use generic class type? But what about CompareTo? Or maybe combine with Element class and place CompareTo there?
I suppose it is feasible. :)
public void insert(Object o)
{
Element el = new Element(o);
// initializing and setting iterators
while(!it.isDone() && ((it.current().getValue())).CompareTo(o)<0)
// it.current() returns Element of List
{
//move interators
}
//...
}
You have two options:
make each object's class implement java.lang.Comparable and write the comparison logic for each class there, then just accept Comparable instead of Object and call compareTo()
create a comparator property of your list and set it on construction. The concrete comparator (implementation of java.util.Comparator) should know how to compare the objects that are put in this particular instance of your list.

Categories