|
nick woodward wrote:On second glance I suppose the compiler can't catch it because it's still possible for a subclass of BlackInk to implement the interface? (with the compiler not knowing what b actually is at compile time). Right?
nick woodward wrote:I was just so confident in my wrong answer (that it wouldn't compile).
nick woodward wrote:but I'm surprised that marking the actual reference itself (final BlackInk b) as final doesn't do the same.....
Steffe Wilson wrote:
Line 6 - I think your comment is correct but the comment is slightly ambiguous so for clarity: the problem raised by the compiler here is with the cast not the assignment. On RHS Dog and Table aren't related so the cast is flagged as an error by the compiler.
** comments edited - it's actually really difficult to add 'lineX' style comments from the small editing window (they also won't match Steffe's response as I'm redoing them):
line 1 - Compiler error. Dog and Table are two unrelated classes.
line 2 - Compiler error. Strokable IS-NOT-A Dog (Dog IS-A Strokable)
line 3 - Compiler error. Table and Dog are two unrelated classes
line 5 - ClassCastException. new Animal() *could* be a Cat. But it isn't at run time.
line 6 - as with line 5.
line 10 - ClassCastException. Cats aren't strokable - but the compiler could be a cat person and believe that maybe a subclass of cat was.
line 11 - ClassCastException. Animals aren't either - but again the return type 'Animal' could be a strokable subclass. It isn't.
line12 - Demonstrating that making the class final tells the compiler that this cannot be a subclass, and therefore cannot be strokable.
Steffe Wilson wrote:That's my take anyway, lets wait for the meastro.
Steffe Wilson wrote:Yeah sorry about line number confusion, I copy pasted your code to my editor and it concat'd some lines and threw the line nos off.
re your last batch, yep agreed plus:
line 7 - compiler error is on the assignment rather than the cast (C ISA A so cast is ok)
line 11 - class cast exception because A is not instanceof I
nick woodward wrote:RE the PM about the inline post comments: I cannot edit that post anymore, but typed the explanations with line numbers if someone wants to merge them:
nick woodward wrote:As for the final BlackInk b = new BlackInk(); not doing the same as making the class final - I think this is an extention of my (same) confusion! I assume your answer would be that the compiler doesn't look at the RHS... so doesn't know if b is a subclass (and final in this context doesn't prevent subclassing, just reassignment an object to this variable) - but with it being final and initialised on that line, why can't the compiler see? it seems similar to a compile time constant.
Roel De Nijs wrote:
Steffe Wilson wrote:That's my take anyway, lets wait for the meastro.
I assume that's me But your explanation is absolutely spot-on! So have a cow for such an excellent post.
So let's have a look at the first code snippetThe compiler is not interested in which object is created here, the compiler only wants to know the type of the expression new A(). That's really the only thing the compiler cares about. Why? Because that's the only thing the compiler needs to determine if this cast is a valid one. So from the compiler's point of view, the line B b = (B)new A(); is equivalent withSo the compiler knows that new A() will evaluate to class A, and because classes A and B are incompatible types, the compiler gives a compiler error.
And with the second code snippet, the compiler does exactly the sameThe compiler knows new A() will evaluate to class A, and because classes A and B belong to the same class hierarchy, the compiler is happy with the cast and won't give a compiler error. (But you'll get a ClassCastException at runtime)
And I agree with you that it's easy to spot that new A() will never be a B object and thus the cast will fail (at runtime). So to answer your question: why does the compiler does not flag this one as a compiler error? You'll probably know the answer: because the compiler does never execute any code Let's say for a few seconds, the compiler would execute code. Let's examine the consequences of this change using the following code statementsSo to have consistent behavior, all 3 lines in the main method should be flagged as a compiler error. Because they will always create an A instance. I think we can agree that the analysis of this code will take much longer to evaluate and verify, both for the compiler and developers, than the current (static) code analysis. So instead of compiling your classes (application) in a few (milli)seconds, it would take several minutes. And the compiler has to flag all 3 lines as a compiler error; otherwise compilation would not be consistent and it would be even harder to tell/explain when a statement will be flagged as a compiler error (or not).
That's why I like this simple and easy rule so much! The compiler does never execute any code! I don't think it can get any easier than this
Now let's see if you have understood all my ramblings. And I noticed you have already practiced a lot, so this should be a walk in the park for you What's the result of this code snippet?
Hope it helps!
Kind regards,
Roel
Roel De Nijs wrote:
final String s1 = "nick";
final String s2 = new String("roel");
switch (args[0]) {
case s1:
case s2: // compiler error
}
}[/code]
nick woodward wrote:right. the assignment B b1 = (B) is fine.
I want to say that (B)(Object) create(); is correct because I'm promising the compiler that:
create is of type A and A IS-AN Object. The question is, am I'm promising the compiler that Object is of type B, or does it fail the IS-A test.
I'm going with it compiles fine because Object and B are related, so the compiler should take my word for it. But it's a ClassCastException because we are lying to the compiler. A is an object, but isn't a B.
nick woodward wrote:nice! I would've fallen for that hook line and sinker in the exam.
that's going on an index card!
Roel De Nijs wrote:
nick woodward wrote:nice! I would've fallen for that hook line and sinker in the exam.
that's going on an index card!
Maybe I should start writing a book and ask big bucks for it, instead of giving all this awesome hints and tips for free Or maybe I could ask Oracle if I could write some of the exam questions. That sounds even more fun and less work
nick woodward wrote:you laugh, but i mentioned to you before (didnt i?) that you should start keeping a list of your 'best of' answers. at worst you'd have a great reference to help on here (saving you time) and at best - honestly you'd have enough for a book or some sort of mini enthuware. i'd buy it.
nick woodward wrote:
Steffe Wilson wrote:line 7 - compiler error is on the assignment rather than the cast (C ISA A so cast is ok)
line 7 - isn't that what I wrote? yeah the problem is that A isn't a C so can't be assigned.
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |