-2

I have been experimenting with instanceof in my Java code.

public class Test {
    public static void main(String[] args) {
        String favoriteFood = "sandwich";
        boolean flag = favoriteFood instanceof StringBuilder; //incompatible types
    }
}

I get an error from flag because String cannot be cast to StringBuilder. I understand that testing a String to check if it is an instance of StringBuilder is illogical because Strings can never be cast as StringBuilders. I also understand the benefits of failing fast. However, is there any way to still run this test and return false? I have looked at related posts, but they have more to do with why there is an error than what to do about it.

(I know there is no practical need to do this. I just want to know if this can be done. If yes, then how? If not, then why not?)

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
K Man
  • 602
  • 2
  • 9
  • 21
  • 2
    Why would you want to run a test that will always fail? – Carcigenicate Apr 27 '19 at 13:55
  • The compiler has no problem checking if 2 + 2 = 5. Any suggestions? – K Man Apr 27 '19 at 13:56
  • 1
    That doesn't mean that there's any point in testing for it. I'm just asking because this sounds like an XY Problem. – Carcigenicate Apr 27 '19 at 13:57
  • `boolean flag = false;` – khelwood Apr 27 '19 at 13:57
  • Haha. Good one, khelwood. Carcigenicate, I am asking out of purely theoritical curiosity. Can it be done? – K Man Apr 27 '19 at 13:59
  • You should look at https://stackoverflow.com/questions/496928/what-is-the-difference-between-instanceof-and-class-isassignablefrom – emory Apr 27 '19 at 14:12
  • have you tried `2 + 2 = 5`? (with Java compiler) [documentation of `instanceof`: "*If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error (§15.16), then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.*"] – user85421 Apr 27 '19 at 14:34
  • "*has no practical use*" is kind of the same as "*not useful*" - one of the reasons listed for downvoting (just my opinion, not downvoting because it shows something interesting, not so known). Maybe you should invest more time answering question (or posting useful ones....) – user85421 Apr 27 '19 at 14:45
  • 1
    @KMan: Please stop added adendums to the question. People can see that you have accepted an answer, so repeating that in the question serves no purpose. – Nicol Bolas Apr 27 '19 at 15:15
  • @Nicol Bolas, it does insofar as it prevents further downvotes to my question. – K Man Apr 27 '19 at 15:18

2 Answers2

3

The simplest approach is:

boolean flag = false;

but if that's unappealing to you for some reason, you can write:

boolean flag = ((Object)favoriteFood) instanceof StringBuilder; // false

and then bribe a coworker to let it past code review.

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • This is wrong on so many levels, but hey, the guy asked for it lol :D – kiselitza Apr 27 '19 at 14:00
  • Thank you for humoring me, ruakh. @K15L33, I have already acknowledged that my question is purely theoretical and that there is no practical need for this test. – K Man Apr 27 '19 at 14:06
  • 1
    I missed the edit, but still, the only thing these 2 have in common is a "mother of all objects", Object itself :) @KMan – kiselitza Apr 27 '19 at 14:09
  • @K15L33: FWIW, they also both implement `CharSequence`. – ruakh Apr 27 '19 at 14:13
  • @ruakh nice touch, although it's partial hit, but it should work as well i think. Interface is an interface after all – kiselitza Apr 27 '19 at 14:16
1

The answer to If not, then why not? is "because the language spec says so" (see comment by Carlos H.).

And the answer to "why does the language spec say so" is that language definers have this tendency to outlaw constructs that make no sense whenever they can, and this tendency is inspired by their belief that in doing that, they are helping you to write better code.

EDIT

re. "does defining a boolean as (2 + 2 == 5) make any more logical sense than ..." : no, it doesn't, but :

(a) it is impossible (that is, logistically infeasible) for language definers to inventorize all the things that could be written but make no logical sense (*)
(b) this kind of problem boils down to proving the emptiness of a set (e.g. proving that the set of all possible instances of String that are also instances of StringBuilder is empty) and proving the emptiness of a set in general as a problem is NP-hard. Given specific extra information, it might be possible and is sometimes done, e.g. given a type hierarchy that almost literally says "no String can also be a StringBuilder". But in general, that is undoable. Which is why you'll always find cases if only you keep searching hard enough.

(*) For your sense of "logical sense", but what you (/we all) really mean, is really just "good programming practice", one of which would be "avoiding obfuscated ways of writing false". It might seem counterintuitive to you, but logic has no concept of "logical sense". 2+2==5 is just another logical proposition, and it happens to be false. Logic does not complain about falsehoods, it just observes them.

(PS I know I used "makes no sense" too, shouldn't have, but I allowed myself to get carried away.)

Erwin Smout
  • 18,113
  • 4
  • 33
  • 52
  • I see your point, but how does defining a boolean as (myString instanceof StringBuilder) make any less logical sense than another boolean defined as (2 + 2 == 5)? – K Man Apr 27 '19 at 14:59