Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Is casting required if we pass an object as an argument in an method?  RSS feed

 
Abhay Bhatt
Ranch Hand
Posts: 64
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was reading about equals and hashcode method in a journal of javaranch:- javaranch journal

In the code presented as the example in the above link, observe Line 13. I couldn't understand why object 'obj' was casted to 'Test' when already a check has been made that it belongs to the same class(ie Test) in Line 10.

I googled a bit about this and it seemed to me that casting is generally required in such cases but I am not sure about my inference and also couldn't understand why it is required, obviously, if my inference was correct.

Any help would be much appreciated. Thanks.
 
Henry Wong
author
Sheriff
Posts: 23283
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Abhay Bhatt wrote:
In the code presented as the example in the above link, observe Line 13. I couldn't understand why object 'obj' was casted to 'Test' when already a check has been made that it belongs to the same class(ie Test) in Line 10.

I googled a bit about this and it seemed to me that casting is generally required in such cases but I am not sure about my inference and also couldn't understand why it is required, obviously, if my inference was correct.


The purpose of the check, prior to line 13, is to make sure that the cast at line 13 does not fail at runtime. Alternatively, it is also possible to not do the check, and have code in place to deal with the cast exception at runtime.

In the case of the compiler, it runs ... well ... at compile time, and not run time. And additionally, it must follow the Java Language Specification on the validity of the code. The JLS, and the compiler that implements it, is ridiculously complex as it is. Imagine how much more complex it would be, if at compile time, the compiler had to work out all possibilities across multiple lines of code (and methods), just for determining whether an explicit cast is needed.

In theory, it is possible. And it is possible in the future, that the JLS and compiler will allow for this check at compile time... but it currently doesn't, and you are currently not allowed to do an implicit cast from a super class type to the subclass type.

Henry
 
Abhay Bhatt
Ranch Hand
Posts: 64
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:

The purpose of the check, prior to line 13, is to make sure that the cast at line 13 does not fail at runtime. Alternatively, it is also possible to not do the check, and have code in place to deal with the cast exception at runtime.

Henry


It seems that I asked you why X is there given that Y is there, and you are saying that Y is there so that X can be there or X doesn't fail. So, I am a little confused and obviously this didn't resolved my original query. Thanks anyways.
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Abhay Bhatt wrote:In the code presented as the example in the above link, observe Line 13. I couldn't understand why object 'obj' was casted to 'Test' when already a check has been made that it belongs to the same class(ie Test) in Line 10.
I know it's too large code but I recommend to peruse the comments in code to clear your doubt.
BaseClass Code:

SubClass Code:
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Output:
*****BaseClass's reference and object*****
BaseClass equals method called:
baseClassMethod method called:
classAge: 50

*****BaseClass's reference and SubClass's object*****
SubClass equals method called:
baseClassMethod method called:
classAge : 50

*****After casting BaseClass's reference to SubClass's reference*****
onlySubClassAge: 10
classAge: 30

*****BaseClass's reference and SubClass's object*****
SubClass equals method called:
baseClassMethod method called:
subClassMethod method called:
classAge: 30
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please click on this button at top left side corner to hide menus and see post in full screen mode so you can read it properly. After click it will turn into means your in full screen mode.
Content minimized. Click to view
 
Henry Wong
author
Sheriff
Posts: 23283
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Abhay Bhatt wrote:
Henry Wong wrote:
The purpose of the check, prior to line 13, is to make sure that the cast at line 13 does not fail at runtime. Alternatively, it is also possible to not do the check, and have code in place to deal with the cast exception at runtime.

It seems that I asked you why X is there given that Y is there, and you are saying that Y is there so that X can be there or X doesn't fail. So, I am a little confused and obviously this didn't resolved my original query. Thanks anyways.


I was trying to give you some context on why the Java compiler behaves in a certain way, and why some stuff that seems obvious to you doesn't to the compiler (plus you took the response out of context, as that paragraph is just the setup for the next two).

... but if you don't care about the context, then to directly answer your question ....  X is there because that is how the language is defined. It doesn't matter that Y is there. There is nothing in the specification that says that X doesn't have to be there given that Y is there.

Henry
 
Abhay Bhatt
Ranch Hand
Posts: 64
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ganish Patil wrote:I know it's too large code but I recommend to peruse the comments in code to clear your doubt.


I really appreciate your humongous effort .

Now, I realize that my doubt/confusion was because of a simple ignorance about the 'getClass' method. I didn't knew that it returned the object type at run time and not compile time . In your wordings, it will return the 'object type' and not its 'class reference'.

I came to this realization when I was about to post a reply to you arguing that I am still in doubt, but at last moment I decided to do a review of my thought process and then it came to me that I might be assuming wrong about getClass method, so I googled and...

Needless to say that your answer obviously helped a lot, albeit in a bit indirect way It also got me refreshed with the nuances of casting which I didn't remembered in detail.

On a different and lighter note....is it really 'Ganish'? It ought to be 'Ganesh' I suppose.
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:The purpose of the check, prior to line 13, is to make sure that the cast at line 13 does not fail at runtime. Alternatively, it is also possible to not do the check, and have code in place to deal with the cast exception at runtime.
That is what he tried to explain to you. Let's see in practical way. In below example in one situation check is made at compile time and in second at runtime.

That was all about .getClass() checking and yes getClass() returns the runtime class of this Object.
Abhay Bhatt wrote:I came to this realization when I was about to post a reply to you arguing that I am still in doubt
I think yes you are ,Now why to cast
In below code, using objctObj2 you can't access age field of Test class b'cause it is not in Object class and we are using reference of Parent class i.e. Object class.

To get access to that age field you must cast reference variable of type Object to Test like this

Same thing they did in that hasCode example to access num and data of Test class. Do one thing just remove that casting and try to access just by obj reference variable, you will get CE as I mentioned above
Abhay Bhatt wrote:is it really 'Ganish'? It ought to be 'Ganesh'
नाम में क्या रखा है, लोग चेहरे भूल जाते है ! (English Version: People forget faces then what's the value of name),hope translated correctly
Jokes apart, Hope you got why we must cast,Thank you for appreciation.
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As you are also a member of this beautiful family so worth reading Patience Is A Virtue
 
Abhay Bhatt
Ranch Hand
Posts: 64
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ganish Patil wrote:
Same thing they did in that hasCode example to access num and data of Test class. Do one thing just remove that casting and try to access just by obj reference variable, you will get CE as I mentioned above



Hi Ganish,

Sorry for replying so late, to a part of your answer. Actually at that time, I just searched for the answer to my specific question in your comment/answer, and didn't read properly the rest of it. I recently ran again into a problem related to this casting, and read your whole reply for reference. You can have a look for my problem at the below link:-

Another related question asked by me at javaranch

If you look at the original post/comment/question, you will see that it comprises of two questions. The latter(below) part is solved, so no need to pay attention to that. Just look at the former(top) portion.

I understand your reply here, a part of which I quoted. Your argument rests/depends on the presumption that 'Test' is the child class of the class reference(class type at compile time) of object 'obj'. But I don't see the statement 'Class Test extends some other class' in the declaration/define statement. So, would we be right in making that presumption? On reflecting, I conclude that probably we would, as even if authors of that code wanted to write that, what they would have written as the parent class name? May be its just implied implicitly that 'Test' has a parent class(other than 'Object' class, obviously!) But I am not too sure, so just wanted to double check or confirm by having second opinions. So, what do you think?
 
Junilu Lacar
Sheriff
Posts: 11135
160
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When there is no explicit extends clause in a class declaration, it implies that the class extends Object.

It seems to me that your confusion arises from you not understanding the difference between a reference variable's declared type and the actual object's runtime type. They are different or rather they can be.

On line 4, the obj variable is declared as a reference to an Object but it is made to reference an instance of Test. Line 5 will print "Test".

On line 7, the obj variable is assigned the value of reference s, which is a reference to the String "foo". Line 8 will print "String".

The same principle applies to the Object parameter of the equals() method.

The parameter to the equals() method has a declared type of Object so that it can accept a reference to any object. The actual object's runtime type may not necessarily be Object though; it can be anything. Given that the runtime type of the object referenced by the obj parameter can be anything, you have to first check what that runtime type is and only when you are sure that the object's runtime type is actually Test can you safely cast obj to Test.
 
Abhay Bhatt
Ranch Hand
Posts: 64
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please ignore the comment, part of which I am quoting below:-



I understand your reply here, a part of which I quoted. Your argument rests/depends on the presumption that 'Test' is the child class of the class reference(class type at compile time) of object 'obj'. But I don't see the statement 'Class Test extends some other class' in the declaration/define statement. So, would we be right in making that presumption? On reflecting, I conclude that probably we would, as even if authors of that code wanted to write that, what they would have written as the parent class name? May be its just implied implicitly that 'Test' has a parent class(other than 'Object' class, obviously!) But I am not too sure, so just wanted to double check or confirm by having second opinions. So, what do you think?

On gaining more clarity, I think that the above statements are confusing. If there had been a option of deleting, I would have deleted it. I say that I don't see the statement of 'Class Test extends some other class' in the declaration/define statement. Why would I? Since 'Object' class is the class type of 'obj', and it is the default parent of all classes. There is never or no need of an explicit declaration mentioning that. Above is a result of incorrect understanding and ignorance on my part, which I cleared in the other thread - the link to which I mentioned in the same comment.
 
Knute Snortum
Sheriff
Posts: 4073
112
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think it's good for the thread to have all the comments, even the ones that sound unclear, so that someone following the thread can see the transition from confusion to clarity.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!