Can someone please explain the difference between this and getClass in Java?
Aren't they the same? getClass returns the class of an object and this does the same thing, right?
The difference between an object and a class
No, they are pretty different, so much that it doesn’t make much sense to compare them.
this can be regarded as a constant reference to the containing object. So not a class, and not being a method it doesn’t return anything. It just is a reference.
getClass() is a method and returns a reference to an object’s class. So not the object itself. Also being a method you can trivially call getClass() on a different object — any object, in fact — whereas this is always the containing object.
An example may demonstrate it. The following isn’t meant to be meaningful as a program that anyone could use for an external purpose.
package ovv.so.objects.basic;
public class ThisAndGetClassDemo {
int i;
public void foo() {
i = 3;
System.out.println(this);
System.out.println(getClass());
System.out.println(this.getClass());
System.out.println("A string".getClass());
}
#Override
public String toString() {
return "ThisAndGetClassDemo " + i;
}
public static void main(String[] args) {
new ThisAndGetClassDemo().foo();
}
}
Output from the program is:
ThisAndGetClassDemo 3
class ovv.so.objects.basic.ThisAndGetClassDemo
class ovv.so.objects.basic.ThisAndGetClassDemo
class java.lang.String
So you see:
this gives us the object (printing it implicitly calls toString() and then prints the return value).
getClass() and this.getClass() produce the same output. Calling getClass() without qualification (without mentioning which object’s getClass method we want to call) calls the object’s own getClass method — exactly the same as what this.getClass() does. In both cases the class is printed, not the object itself.
Finally "A string".getClass() gives us the String class because "A string" is an instance (an object) of that class.
I do understand your confusion, though. Every now and then we hear programmers being sloppy and in what they say not making that distinction between an object and a class — in particular in situations where there is only one object of a given class in play (which happens often). It’s like saying “horse” without making explicit whether I mean the horse (the object; given there is only one around) or I mean the concept of a horse (the class).
Related
This question already has answers here:
Dynamic dispatch and binding
(2 answers)
Closed 2 years ago.
Im confused, when i use getClass( ) from a superclass reference variable that's pointing to a subclass object, the result is the subclass.
Heres a simple example:
public `class` TestGetClass
{
public static void main(String[] args)
{
Object obj = new Integer(20);
System.out.println("obj class: " + obj.getClass());
}
}
The output gives me the Integer class instead of the Object class.
obj class: class java.lang.Integer
Can someone explain please
What you're looking for is simply:
Object.class.
obj.getClass() in java could plausibly be interpreted in two different ways:
It means: Take the expression 'obj', which is a reference (i.e., a pointer). Follow the pointer and find the object it is pointing at. Ask that object what its type is.
just like 1, except, because the variable type was Object, invoke the implementation of the getClass() method from the java.lang.Object class. i.e., no dynamic dispatch.
It means: Take the locally declared variable named obj. What type did I declare it as, right here in this method? Don't care about the object/pointer at all, just the declaration.
Now, the java lang spec is crystal clear: In java, #1 is what happens. #2 is not available (you can't opt out of dynamic dispatch. As a matter of obvious language design, private methods don't do it because they don't need it, and static methods don't do it because, by being static, they just aren't a part of the hierarchy in the first place - so those seeming exceptions really don't apply. There is no other way to opt out).
Here's the thing about option #2 though: is completely pointless.
In java, you can't have mystery meat variables. Somebody declares them, and the type is written right there in the source file. There is no such thing as 'eh, figure it all out at runtime'. Even java10's var doesn't work that way (it's still locked in, for sure, at compile time).
So, you already know. It is object, what point is there to repeat it?
If you want a java.lang.Class<?> instance that represents Object, there's syntax for this. it is:
Class<?> objClass = Object.class;
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(){
}
}
I have a class called Entity which is an abstract super-class for many other objects I use throughout my program (for this example, the Apple class).
In many of the methods, I print debugging statements by printing the class name that the statement is printed from, followed by the actual debugging message. To my surprise, however, when I call the inherited method from an instance of Apple, the class name of Apple is printed rather than the class name of Entity (which is where the method is actually located).
To take a related example that's easier to post a code snippet for, I have overridden toString() like so:
public abstract class Entity {
private String name;
#Override
public String toString() {
return getClass().getSimpleName() + " " + (name != null ? name : super.hashCode());
}
}
Because I do not further override this method in the Apple class, I would expect this first part of the returned String to be Entity, not Apple. And yet it returns Apple (which is actually nice that it works this way for this use case, but still somewhat baffling).
I tried looking at the implementation for Object#getClass(), but was unable to since it is declared as a native method.
public final native Class<?> getClass();
Can anyone explain why this happens?
You're calling getClass(). That always returns a reference to the Class object associated with the actual execution-time type of the object, not the class for the compile-time type of the expression you call it on. So for example:
Object foo = "this is a string";
Class<?> clazz = foo.getClass();
clazz will refer to the class for String, not the class for Object.
You don't need to look at the implementation of getClass() - just look at the documentation:
The Class object that represents the runtime class of this object.
Note the "runtime" bit, as in "determined at execution time, not at compile time".
In this case I think it's entirely reasonable to return the execution-time class name within the result of toString(), but if you ever really really wanted the Entity class, you could just use Entity.class instead.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Do interfaces inherit from Object class in java
package inheritance;
class A{
public String display(){
return "This is A!";
}
}
interface Workable{
public String work();
}
class B extends A implements Workable{
public String work(){
return "B is working!";
}
}
public class TestInterfaceObject{
public static void main(String... args){
B obj=new B();
Workable w=obj;
//System.out.println(w.work());
//invoking work method on Workable type reference
System.out.println(w.display());
//invoking display method on Workable type reference
//System.out.println(w.hashCode());
// invoking Object's hashCode method on Workable type reference
}
}
As we know that methods which can be invoked depend upon the type of the reference variable on which we are going to invoke. Here, in the code, work() method was invoked on "w" reference (which is Workable type) so method invoking will compile successfully. Then, display() method is invoked on "w" which yields a compilation error which says display method was not found, quite obvious as Workable doesn't know about it. Then we try to invoke the Object class's method i.e. hashCode() which yields a successful compilation and execution. How is it possible? Any logical explanation?
The intuitive answer is that regardless of what interface you refer to, the object implementing the interface must be a subclass of Object.
Section 9.2 of the JLS specifically defines this behaviour: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
i.e. all interfaces are assumed to contain method signatures corresponding to methods in the Object class.
I think what's happening here is that even though w is known only to be Workable, all objects must derive from Object, so no matter what class w eventually is, it must have the Object methods.
The reason w.display() doesnt work is as you have save the reference as your interface type. The compiler only sees the methods exposed by the interface. If you were to call ((B)w).display() this would work. You are able to call hashCode() as the compiler is smart enough to know that interfaces are inherited by Objects and all object's superclass is Object
in java, is it possible to access the instance to which a method belongs, given only the method?
for example:
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
instanceB.receiveMethod(foo);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Object o = foo.getInstanceOwner(); // just made that part up...
}
}
my feeling is that methods belong to classes, not instances of a class, so the answer is no, but maybe there's some sneaky reflection technique i don't know about. i could always pass 'this' along with method foo, but that seems like extra baggage.
Taken from
A Method provides information about, and access to, a single method on a class or interface. The reflected method may be a class method or an instance method (including an abstract method).
A Method permits widening conversions to occur when matching the actual parameters to invoke with the underlying method's formal parameters, but it throws an IllegalArgumentException if a narrowing conversion would occur.
You can call Method#invoke but you will need the instance of the object you want to call the method on, from the method doc:
Invokes the underlying method
represented by this Method object, on
the specified object with the
specified parameters. Individual
parameters are automatically unwrapped
to match primitive formal parameters,
and both primitive and reference
parameters are subject to method
invocation conversions as necessary.
If the underlying method is static,
then the specified obj argument is
ignored. It may be null.
If the number of formal parameters
required by the underlying method is
0, the supplied args array may be of
length 0 or null.
If the underlying method is an
instance method, it is invoked using
dynamic method lookup as documented in
The Java Language Specification,
Second Edition, section 15.12.4.4; in
particular, overriding based on the
runtime type of the target object will
occur.
If the underlying method is static,
the class that declared the method is
initialized if it has not already been
initialized.
If the method completes normally, the
value it returns is returned to the
caller of invoke; if the value has a
primitive type, it is first
appropriately wrapped in an object.
However, if the value has the type of
an array of a primitive type, the
elements of the array are not wrapped
in objects; in other words, an array
of primitive type is returned. If the
underlying method return type is void,
the invocation returns null.
So the TL:DR is unless you have the actual object you want you call the method on, it is not possible.
public class ClassA {
private ClassB instanceB = new ClassB();
// ...
private void sendMethod () {
Method m = ClassA.class.getMethod("foo", null);
instanceB.receiveMethod(m);
}
public void foo () {}
}
public class ClassB {
public void receiveMethod (Method method) {
Class c = method.getDeclaringClass();
}
}
gives you the owning Class. An instance doesn't own methods.
You can do this, but the proper way in your example would be the use of an interface, because that seems to be what you want: You want to pass in an object that ClassB knows how to operate on.
interface Callback {
void foo();
}
public class ClassA implements Callback {...}
public class ClassB {
public void receiveMethod(Callback cb) {...}
}
This is like asking:
"Given an apple from an Apple orchard, which tree owns this apple?"
The answer to which is:
"No idea, since all apple trees produce apples, it could belong to any tree".
... in other words - you must supply an instance from which the method will be called
EDIT
From one of your comments, I gather you are looking for an alternative of the Observer pattern. You say you don't like the messiness of the Observer pattern and that it is not "generic" enough for you.
I would argue that it is probably one of the least messiest patterns in existence, AND interfaces are by definition as generic as things get!
So, perhaps its an implementation problem you're having. Luckily, I have already posted on SO an Observer implementation in JAVA, to demonstrate how powerful and elegant it is.
Polymorphism and Interfaces in Java (can polymorphism be used to implement interfaces...why?)
In fact: reflection is messier than using an interface, since you can't guarantee at compile time that the type of Object you are invoking an instance of a Method on, even supports that method! (without some error checking code). Versus with interfaces, its not possible to even have that problem.