About Question enthuware.ocajp.i.v7.2.1328 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

I don't see any C in your code.
The code you've quoted above will fail at run time because a is pointing to an object of class A, and you are trying to cast it as B. So why do you think it should work? B is A but A is not B.

-Paul.
If you like our products and services, please help us by posting your review here.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by javaman »

Here is code like in question. Added functions in class for clarity:

package LearnJava;

interface I{
}
class A implements I{
void a1(){
System.out.println("A.m1()");
}
}

class B extends A {
void b1(){
System.out.println("B.m1()");
}
}

class C extends B{
void c1(){
System.out.println("C.m1()");
}
}
//And the following declarations:
class LearnJava{
public static void main(String[] args) {
A a = new A();
B b = new B();
a = (B)(I)b;
a.b1();
}
}

Line a = (B)(I)b; compiles ok and gives no RE as the correct answer says. I don't understand what's happening here. Is it a cast from a to b? If so, why does a.b1(); give an compiler error "Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: LearnJava.A.b1"?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

It will be a bit difficult to explain this. But I can try:

At runtime, b refers to an object of class B. Since B implement I, (I)b is valid as compile as well as runtime. Let's calls (I)b as i.
Now, since I is an interface, (B)i is valid at compile time and is valid at runtime because i indeed points to an object of class B. Let's call (B)i as x.
a = x is valid at compile time because x is of type B and B is a A. It is also valid at run time because x indeed points to an object of class B.


a.b1() won't work because the class of reference a is A, which does not have the method b1().


I would suggest you refer to a book to understand this better.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by javaman »

Ok, I understand this is not a cast from a to B...
Thanks for explanation.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by javaman »

Hello,

I try to get my finger behind casting but not 100% sure I get it...

In below code, a.m1(); prints "C.m1()". In plain English it does the following:

B b = new C(); ==>
"Create a reference of type B b and assign to it (aka 'point it to') an instance of subclass C
B a = (B)(I)b; ==>
I tmp = (I)b; // Treat reference to instance C as reference to interface I;
B a = (B)tmp; // treat reference to interface I as reference to
an instance of class B (this is possible because B implements I via A);

WHY does a.m1() not give me the output "B.m1()"? if a points to instance of B it should?
======

Code: Select all

class LearnJava{
	public static void main(String[] args) {
		B b = new C();
		B a = (B)(I)b;
		a.m1();
	}
}
interface I{}

class A implements I{
    public void m1(){
         System.out.println("A.m1()");
    }
}
class B extends A{
    public void m1(){
        System.out.println("B.m1()");
    }
}
class C extends B{
    public void m1(){
        System.out.println("C.m1()");
    }
}
class D extends C{
    public void m1(){
        System.out.println("D.m1()");
    }
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

>>WHY does a.m1() not give me the output "B.m1()"? if a points to instance of B it should?
Because a does not point to an instance of B. It points to an instance of C. That what is polymorphism. http://docs.oracle.com/javase/tutorial/ ... phism.html

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

tn1408
Posts: 28
Joined: Wed Dec 04, 2013 7:57 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by tn1408 »

Hello, Paul I ran the code:
class TestClass{
public static void main(String[] args){
A a = new A();
B b = new B();

a = (B)(I)b;
b = (B)(I) a;
//I i = (C) a;
//I i = (C) a;
}
}
interface I{}
class A implements I{}
class B extends A {}
class C extends B{}

and answer #2: b = (B)(I) a; actually didn't fail.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

That is because you already have "a = (B)(I)b;". You need to comment it out first.
If you like our products and services, please help us by posting your review here.

seanthemill
Posts: 2
Joined: Tue Feb 04, 2014 4:30 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by seanthemill »

Hi,
Given the following code:

Code: Select all

class A{}
class B extends A {}

public class Test {
    public static void main(String[] args) {
        A a = new A();
        A a1=new A();
        B b = new B();
//        a=b;// ok
//        b=(B)a;// ClassCastException
//        a=(A)a1;  // ok
//        a=a1;  // ok
        
      a=(B)a1; // compiles ok, ClassCastException???
    }
}
My question is with the line in bold/red. My understanding is that for the compiler to be ok, it just needs to be satisfied that the classes are in the same hierarchy and as a result it may work (up the tree implicit casting, down the tree requires explicit casting). Whenever I have come across ClassCastException it is because the reference was pointing to an object up the tree e.g. a ref of type B pointing to an object of type A.
The line in question appears to be a ref of type A pointing to an object of type A. The cast to (B) obviously is what is causing the ClassCastException. Can someone explain please what it does to effect this? Is the A ref a, a B ref all of a sudden??

Thanks,
Sean.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

You've written about your understanding about compiler. But then you are talking about ClassCastException, which happens only at run time.
I am not really clear about what you are asking? ClassCastException is thrown whenever the object that you are trying to cast to a reference of another class cannot be cast to that class.

I don't think in your code b=(B)a should throw ClassCastException because a is actually pointing to an object of class B because of a=b; written earlier.
If you like our products and services, please help us by posting your review here.

seanthemill
Posts: 2
Joined: Tue Feb 04, 2014 4:30 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by seanthemill »

Thanks for the reply. I think I have it figured: my confusion was arising because of the fact that given the assignment

Code: Select all

 A a = (B)new A(); // where B extends from A
the type on the left hand side was an A; however this has nothing to do with the cause of the ClassCastException at runtime. Quite simply, a B reference can never point at an object of type A (and that is what the right hand side of the assignment was trying to create).

Given that is the case, the following also holds true:

Code: Select all

A a = (B)new B();   // no issues at compile time or runtime
because a reference of type A can point at any object of type B (because B is-an A via inheritance).

Is that accurate?

Regards,
Seán.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

Yes, that is correct.
If you like our products and services, please help us by posting your review here.

iamslrr
Posts: 6
Joined: Sun Dec 20, 2015 1:23 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by iamslrr »

Consider the following classes :

interface I{
void iMsg();
}

class A implements I{
void iMsg() { }
void aMethod() { }
}

class B extends A {
void bMethod() { }
}

class C extends B{
void cMethod() { }
}


And the following declarations:
A a = new A();
B b = new B();
a = (B)(I)b;
a.bMethod();


Why does a.bMethod cause a compiler error:
Test4.java:35: error: cannot find symbol
a.bMethod();
^
symbol: method bMethod()
location: variable a of type A


After the cast a instanceof B is true.

iamslrr
Posts: 6
Joined: Sun Dec 20, 2015 1:23 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by iamslrr »

Ahhh...
Nevermind!

AristPhil
Posts: 4
Joined: Wed Jan 06, 2016 5:38 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by AristPhil »

I've summarized my understanding of this multiple casting question here: http://www.coderanch.com/forums/posts/l ... 31#3066425
I'd appreciate if somebody interested and competent would find the time to verify, if my understanding is correct. Many thanks!

Sergey
Posts: 39
Joined: Sat Jul 29, 2017 1:04 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by Sergey »

Code: Select all

interface I{}
class A implements I{}
class B extends A {}
class C extends B{}

public  class TestClass {
    public static void main(String[] args){
        A a = new A();
        B b = new B();
        
        
        a=b;
        //b=(B)(I)a;
        b=a; // if "a" is a "b" now, why this line of code is wrong?
   }
 }
if "a" is a "b" now, why this line of code is wrong?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

Your question indicates several misconceptions.
1. It is incorrect to say that "a" is a "b" because "b" is reference variable. You can say "a" points to an object of class B.
2. When you cast a reference of one class to another class, you don't change the actual type of the object that is pointed to by the reference. So when you cast a to B ( i.e. by doing (B) a), you don't convert the object pointed to by the variable a into an object of class B. You merely tell the compiler that a will point to an object of class B at run time.

Thus, at run time, a really has to point to an object of class B for (B) a to succeed at runtime.

I suggest you to read this topic thoroughly from a good book to get your basics right before attempting mock exams.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

st.lisker
Posts: 22
Joined: Sat Jun 30, 2018 6:11 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by st.lisker »

Hello. Is this some difference between 1 and 2 ? :
A a = (B)(I) b; //1
A a = (B) b: //2

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

No, practically, there is no difference.
If you like our products and services, please help us by posting your review here.

st.lisker
Posts: 22
Joined: Sat Jun 30, 2018 6:11 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by st.lisker »

Ok, thank you.

__JJ__
Posts: 125
Joined: Thu Jul 05, 2018 6:44 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by __JJ__ »

This one tripped me up. I'm glad it did because now it's cleared up an obvious misunderstanding that I had.
It seems tricky but actually, if you think about it, it isn't.
Just remember, if A implements I, an A is an I but an I isn't an A.
To reinforce the point, millions of classes implement Serializable; but that doesn't mean that just because X implements Serializable, any Serializable reference can be assigned to a reference variable of type X.

What makes it deceptive is that when you see
a = (I) b;
you know that A is an I, so you think, surely an I can be assigne to variable a. But the compiler just knows that at that point there is something that is an I. It is only known to be an I; it could be any one of millions of classes that is implements I. So you can't just assign it to a variable of type A without explicitly casting it.

tosidis
Posts: 3
Joined: Fri Oct 26, 2018 4:45 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by tosidis »

Hello, I think that this a = (B)(A)b; would also compile and run , even if a is declared like this I a = new A();

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

tosidis wrote:
Sun Nov 25, 2018 6:26 am
Hello, I think that this a = (B)(A)b; would also compile and run , even if a is declared like this I a = new A();
Correct.
If you like our products and services, please help us by posting your review here.

jimmy21
Posts: 3
Joined: Sun Dec 23, 2018 6:38 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by jimmy21 »

Are there any differences betwen:

Code: Select all

 a = (B)(I)b; 
  a = (B)b;
  a = b;

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1328 :

Post by admin »

(I) in (B)(I) is redundant so,
a = (B)(I)b; and a = (B)b; are same.

a = b; is obviously not the same because there is no cast. It is valid here only because type of b is-a A. It may not always work.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: No registered users and 63 guests