I have two classes :
import android.cla;
public class CW {
public static void main(String [] args){
System.out.println(new cla());
}
}
public class Cl {
#Override
public String toString(){
return "LOL";
}
}
In the first class I'm calling the objects toString() method, which has been overriden and printing it to console. It clearly returns "LOL";
I have two questions :
Is it possible to return data while instantiating like this (new cla()) without overriding the objects toString() method; and
What is the proper term for instantiating classes like this (new cla()), that's without declaration like : Object l = new cla()
Thanks. Please correct me on the proper terms.
1 - No it isn't. A 'constructor' is a special method on the class that always returns an object instance of the class. The whole point of the constructor is to return the object. So no, it can't return anything else.
1a - The reason that System.out.println calls the toString method is because you are asking it to print out that object to the screen, and the toString method is the method chosen by the authors of println (and the Java language in general) to give a string representation of the object.
2 - That way of writing isn't really called anything. It's just an expression that you're passing as an 'actual parameter' to the println method. True, it's an expression that instantiates a new object, but it's no different to println("a string"). You could call it an anonymous object if you really wanted to.
2a - (old answer that doesn't actually answer your question but I'll keep it here) That's just called 'using a less derived reference† to a class'. Beware you can only call methods on the type of the reference, so if you added extra methods to your Cl class you couldn't call them from an Object reference. Look into Liskov substitution principle.
† 'less derived' or 'supertype' or 'superclass' or 'more general class' etc...
Related
I have the following classes defined:
class BaseClass {
public String toString()
{
return "I am a: " + getClass().getName();
}
}
class DerivedClass {
public String toString()
{
return super.toString();
}
}
In my main() function I have the following code:
BaseClass b = new BaseClass();
DerivedClass d = new DerivedClass();
System.out.println(b);
System.out.println(d); // not sure why/how this works!
As expected, I do get the correct run-time class types when this code runs:
I am a: BaseClass
I am a: DerivedClass
My question is, how exactly does the call to toString() in my DerivedClass work? In my DerivedClass override of toString(), I'm making a call to super.toString() which seems like it should actually return "I am a: BaseClass" because we're calling toString() on the parent class.
I suspect it may have something to do with the fact that my base class toString() utilizes getClass().getName(), so that when I call it through a subclass object, Java must be detecting my actual object type - but I don't know how it knows to do that...
Sorry if this sounds like a noob question, but I'm still wrapping my head around the concept of polymorphism. If anyone could explain why this works the way it does, I'd appreciate any insight.
getClass() is a polymorphic method. It returns the actual concrete class of the object on which it is called. Since d id of type DerivedClass, its getClass() method returns DerivedClass.class.
You would get the result you expect if the method implementation was
return "I am a: " + BaseClass.class.getName();
Imagine your classes looked like this:
class BaseClass {
#Override
public String toString() {
return "I am a: " + getClass().getName();
}
public Class<?> getClass() {
return BaseClass.class;
}
}
class DerivedClass extends BaseClass {
#Override
public Class<?> getClass() {
return DerivedClass.class;
}
}
Because of the way overriding works, getClass() will always return DerivedClass.class when invoked on an instance of DerivedClass, even when called from the superclass BaseClass. Calling super.toString() doesn't change that, and is in fact entirely unnecessary, since the superclass implementation is inherited by default.
Note that this is just a demonstration of what you can expect when calling getClass(). In real life, getClass() is actually a final native method. Overriding it is not possible or necessary.
Your first question is:
System.out.println(d); // not sure why/how this works!
And it is a good question! After all, you are passing the println method a reference, d, to an instance of DerivedClass. Why would that result in actually calling a method that is named toString()?
The answer to this question lies in the Javadoc for the appropriate println method. The compiler (javac) correctly compiles your code to say that you are interested in calling the println method that takes in an Object. Note that println is an overloaded method and compiler must resolve the right method based on passed argument(s). In this case, the method resolves to println(Object x) which states:
Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().
Then you visit the String.valueOf() method and see:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Bingo! That closes the first loop, either the BaseClass's toString() is called, or DerivedClass's.
The actual reason why the d's getClass() is called has to do with the value of the this reference. As you perhaps know, every instance method in Java (like the toString() one) receives an invisible parameter called the this reference in addition to the arguments that are declared. In this particular case, since the this reference points to d, all the methods are invoked on that reference. The class of d is clearly DerivedClass.
Sometimes we call className.methodName() without creating object for it, I mean without using syntax as className objectName = new constructor() and then call as object.methodName()
When to use className.methodName()?
When to call method using object as object.methodName()?
Explanation of above two cases with example will be appreciated.
What you're referring to is a static method.
Assume that I have this :
public class A {
public static void foo(){
System.out.println("Hooray! I work!");
}
}
You can now do this anywhere else in any other class :
A.foo();
This is because the method is static, which means that it can be called on by the CLASS.
This means that it doesn't require an instance of that class in order for the method to be called.
However, even though it isn't required, you can still do this :
A a = new A();
a.foo();
But since the method foo() is static, instantiating an object A is not required in order to run the foo() method.
First. When you're create at least one static method of a class, you can use this method without creating an instance of class. This is useful, for example, for the creation of methods with independent logic. For example:
public class Checker {
public static Boolean month(int value) {
return (value >= 1 && value <= 12);
}
}
You need check correct value of month many times. But what to do each time to create the object. It is much effective to use a static method.
Second. When you create the object, the object is stored in the memory and you get a link to it. Then the object can be used for example to save at the list.
Method at this object is specific. You can save class data and do specific operation with member of this class. For example:
List<Animals> animalsList = new ArrayList<>();
Animal animal = new Animal("dog");
int legs = animal.getCountLegs(); // specific function for object
animalList.add(animal); //save if you need
// use list of object
For every class, we have a Object called as class object which is YourClass.class object. static methods are invoked based on meta-data on those objects. For instances of a class, methods are invoked on the actual instances. Both static and non-static methods are present on method area.
There is no different between 1 and 2 point, because in during compilation compiler makes ClassName.staticMethod() instead of instance.staticMethod().
Static methods in java belong to the class (not an instance of it). They use no instance variables and will usually take input from the parameters, perform actions on it, then return some result. Instances methods are associated with objects and, as the name implies, can use instance variables.
I have the following code.
class Test {
int i = 0;
Test() {
System.out.println(this);
System.out.println(this.i);
}
}
public class Demo extends Test {
int i = 10;
Demo() {
super();
System.out.println("calling super");
System.out.println(this);
System.out.println(this.i);
}
public static void main(String[] args) throws IOException {
Demo d = new Demo();
}
}
O/P : Demo#2e6e1408
0
calling super
Demo#2e6e1408
10
When I execute the program and print the value of "this", in both super class constructor as well as in child class constructor, the value of this (address location) is displayed as childClassName#someValue .. My question is, why dont I get the value of Test i.e, Test#someVal (Super class) when I print value of "this" in the super class.. ASAIK, Super class will also have a place/location in memory, so, why am I not getting Test#someValue in the first SOP...
PS : I know variables are referenced based on the reference type (LHS) and methods are called based on the object type (RHS)..
When I execute the program and print the value of "this", in both super class constructor as well as in child class constructor, the value of this (address location)...
The output of System.out.println(this) with the default Object#toString is not the address of the instance in memory. It's just the name of the class and the instance's hash code, nothing more. From the documentation:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
It's true that the hashCode documentation says
This is typically implemented by converting the internal address of the object into an integer...
but it also says
...but this implementation technique is not required by the JavaTM programming language.
...and of course the JVM is free to move instances around in memory as necessary, but isn't allowed to change the hashCode.
...why dont I get the value of Test i.e, Test#someVal (Super class) when I print value of "this" in the super class.
There is one instance. That instance is of the subclass. When you do System.out.println(this), it doesn't matter whether you do that in the base class or the subclass, it's still the same object instance you're using. That one object has features it gets from the subclass and also features it inherits from the superclass, but there aren't two separate instances; there's one instance with a combined set of features. super isn't an object reference, although it looks a bit like one; it's a syntax mechanism for specifically asking the compiler to use a feature the instance inherits from the superclass rather than the equivalent feature of the instance (in case they're different).
Demo is a composition of 3 classes: itself, Test and Object. But an instance of Demo is one object, in memory it consists of fields of its super class + its own fields: Test.i + Demo.i (Object has no fields).
System.out.println(this);
Why would you use 'this' in the brackets? Is it for printing the references? Or as in the code below for comparing if the object points to the same reference?
public void compareDrzewo(Drzewo tree)
{ if (tree == this)
{ System.out.println("true"); }
else { System.out.println("false"); }
main method code
Drzewo name1 = name2;
name1.compareDrzewo(name2);
The other examples of the use of 'this.' are quite straight forward (inner class etc.) Please comment only on this or similar use.
That instance has a toString() method associated with it, which means it will invoke it to print out meaningful information, or it uses Object's toString() (meaning it'll print out a memory location, which is much less useful).
System.out.println(this)
is the same as
System.out.println(this.toString());
So if the class of which this is an instance overrides the toString method, that line of code would be meaningful.
You use this to refer to the current object.
One example is when your want to refer to the current instance of your class, so if you need to call a method with your class, for example something.equals(this) or something == this.
Another example is explicitly specifiying a class instance of a variable rather than a local instance, for example a setter:
public void setMyVar(String myVar) {
this.myVar = myVar;
}
So myVar is the variable declared in the method, this.myVar is the variable declared in your class.
Yesterday I had a two-hour technical phone interview (which I passed, woohoo!), but I completely muffed up the following question regarding dynamic binding in Java. And it's doubly puzzling because I used to teach this concept to undergraduates when I was a TA a few years ago, so the prospect that I gave them misinformation is a little disturbing...
Here's the problem I was given:
/* What is the output of the following program? */
public class Test {
public boolean equals( Test other ) {
System.out.println( "Inside of Test.equals" );
return false;
}
public static void main( String [] args ) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println( count++ );// prints 0
t1.equals( t2 ) ;
System.out.println( count++ );// prints 1
t1.equals( t3 );
System.out.println( count++ );// prints 2
t3.equals( o1 );
System.out.println( count++ );// prints 3
t3.equals(t3);
System.out.println( count++ );// prints 4
t3.equals(t2);
}
}
I asserted that the output should have been two separate print statements from within the overridden equals() method: at t1.equals(t3) and t3.equals(t3). The latter case is obvious enough, and with the former case, even though t1 has a reference of type Object, it is instantiated as type Test, so dynamic binding should call the overridden form of the method.
Apparently not. My interviewer encouraged me to run the program myself, and lo and behold, there was only a single output from the overridden method: at the line t3.equals(t3).
My question then is, why? As I mentioned already, even though t1 is a reference of type Object (so static binding would invoke Object's equals() method), dynamic binding should take care of invoking the most specific version of the method based on the instantiated type of the reference. What am I missing?
Java uses static binding for overloaded methods, and dynamic binding for overridden ones. In your example, the equals method is overloaded (has a different param type than Object.equals()), so the method called is bound to the reference type at compile time.
Some discussion here
The fact that it is the equals method is not really relevant, other than it is a common mistake to overload instead of override it, which you are already aware of based on your answer to the problem in the interview.
Edit:
A good description here as well. This example is showing a similar problem related to the parameter type instead, but caused by the same issue.
I believe if the binding were actually dynamic, then any case where the caller and the parameter were an instance of Test would result in the overridden method being called. So t3.equals(o1) would be the only case that would not print.
The equals method of Test does not override the equals method of java.lang.Object. Look at the parameter type! The Test class is overloading equals with a method that accepts a Test.
If the equals method is intended to override, it should use the #Override annotation. This would cause a compilation error to point out this common mistake.
Interestingly enough, in Groovy code (which could be compiled to a class file), all but one of the calls would execute the print statement. (The one comparing a Test to an Object clearly won't call the Test.equals(Test) function.) This is because groovy DOES do completely dynamic typing. This is particularly of interest because it does not have any variables that are explicitly dynamically typed. I have read in a couple of places that this is considered harmful, as programmers expect groovy to do the java thing.
Java does not support co-variance in parameters, only in return types.
In other words, while your return type in an overriding method may be a subtype of what it was in the overridden, that is not true for parameters.
If your parameter for equals in Object is Object, putting an equals with anything else in a subclass will be an overloaded, not an overridden method. Hence, the only situation where that method will be called is when the static type of the parameter is Test, as in the case of T3.
Good luck with the job interview process! I'd love to be interviewed at a company that asks these types of questions instead of the usual algo/data structures questions that I teach my students.
I think the key lies in the fact that the equals() method doesn't conform to standard: It takes in another Test object, not Object object and thus isn't overriding the equals() method. This means you actually have only overloaded it to do something special when it's given Test object while giving it Object object calls Object.equals(Object o). Looking that code through any IDE should show you two equals() methods for Test.
The method is overloaded instead of overriden. Equals always take an Object as parameter.
btw, you have an item on this in Bloch's effective java (that you should own).
Some note in Dynamic Binding (DD) and Static Binding̣̣̣(SB) after search a while:
1.Timing execute: (Ref.1)
DB: at run time
SB: compiler time
2.Used for:
DB: overriding
SB: overloading (static, private, final) (Ref.2)
Reference:
Execute mean resolver which method prefer to use
Because can not overriding method with modifier static, private or final
http://javarevisited.blogspot.com/2012/03/what-is-static-and-dynamic-binding-in.html
If another method is added that overrides instead of overloading it will explain the dynamic binding call at run time.
/* What is the output of the following program? */
public class DynamicBinding {
public boolean equals(Test other) {
System.out.println("Inside of Test.equals");
return false;
}
#Override
public boolean equals(Object other) {
System.out.println("Inside #override: this is dynamic binding");
return false;
}
public static void main(String[] args) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println(count++);// prints 0
t1.equals(t2);
System.out.println(count++);// prints 1
t1.equals(t3);
System.out.println(count++);// prints 2
t3.equals(o1);
System.out.println(count++);// prints 3
t3.equals(t3);
System.out.println(count++);// prints 4
t3.equals(t2);
}
}
I found an interesting article about dynamic vs. static binding. It comes with a piece of code for simulating dynamic binding. It made my code a more readable.
https://sites.google.com/site/jeffhartkopf/covariance
The answer to the question "why?" is that's how the Java language is defined.
To quote the Wikipedia article on Covariance and Contravariance:
Return type covariance is implemented
in the Java programming language
version J2SE 5.0. Parameter types have
to be exactly the same (invariant) for
method overriding, otherwise the
method is overloaded with a parallel
definition instead.
Other languages are different.
It's very clear, that there is no concept of overriding here. It is method overloading.
the Object() method of Object class takes parameter of reference of type Object and this equal() method takes parameter of reference of type Test.
I will try to explain this through two examples which are the extended versions of some of the examples that I came across online.
public class Test {
public boolean equals(Test other) {
System.out.println("Inside of Test.equals");
return false;
}
#Override
public boolean equals(Object other) {
System.out.println("Inside of Test.equals ot type Object");
return false;
}
public static void main(String[] args) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
int count = 0;
System.out.println(count++); // prints 0
o1.equals(t2);
System.out.println("\n" + count++); // prints 1
o1.equals(t3);
System.out.println("\n" + count++);// prints 2
t1.equals(t2);
System.out.println("\n" + count++);// prints 3
t1.equals(t3);
System.out.println("\n" + count++);// prints 4
t3.equals(o1);
System.out.println("\n" + count++);// prints 5
t3.equals(t3);
System.out.println("\n" + count++);// prints 6
t3.equals(t2);
}
}
Here, for lines with count values 0, 1, 2, and 3; we have reference of Object for o1 and t1 on the equals() method. Thus, at compile time, the equals() method from the Object.class file will be bounded.
However, even though reference of t1 is Object, it has intialization of Test class.
Object t1 = new Test();.
Therefore, at run-time it calls the public boolean equals(Object other) which is an
overridden method
.
Now, for count values as 4 and 6, it is again straightforward that t3 which has reference and initialization of Test is calling equals() method with parameter as Object references and is an
overloaded method
OK!
Again, to better understand what method the compiler will call, just
click on the method and Eclipse will highlight the methods of similar
types which it thinks will call at the compile time. If it doesn't get
called at compile time then those methods are an example of method
overridding.