Classic Java language WTF



  • @morbiuswilters said:

    So, if it took you a couple of seconds to see the problem
    Unlike you, I am unable to read every word of the post simultaneously.  I'll agree that it's obvious what's going on upon reading.  It's nearly 4 years since I worked with Java and that was for a single semester of university.  Actually, Java was our (official) introduction to OOP, after a semester of C.



  • @CodeSimian said:

    Well, I guess where the problem lies depends on your POV.  Based on my oldish Java knowledge, I didn't expect the code to compile at all (and it doesn't under 1.4 and earlier).  Everybody who knows a little bit of Java realizes objects and primitives are not interchangeable.  But along comes this new autoboxing feature which says sometimes objects and primitives are interchangeable, (e.g. not in cases where it would break backwards compatibility.)

    From your POV (and others), the OP's code is stupid, therefore there's no problem (i.e. "You should never write that kind of code, what are you complaining about?").  From my POV, I don't care whether the code is stupid or not.  I think the language should be designed so nobody has to ask "How come the '<' and '>' operators work in this case, but not the '!=' and '==' operators?" regardless of whether it's a stupid question or not. 

    To me, the WTF is not that anyone would rely on that behaviour (they wouldn't), but that one has to ask why does it work that way?  IMO, that was whole point of the OP.

    As for me, I learned a little bit about Java (some of which I had forgotten years ago), so I have no complaints about this thread.

    I agree that it was silly on the part of Sun to specify the odd behavior for auto-boxed primitives, but I don't think it's the point of the OP.  Even if it was, it's like asking "How come Dennis Ritchie thought it was okay for invalid pointers to still possibly work?"  All languages have their pitfalls and posting examples of undefined or "odd" behavior certainly doesn't qualify as a WTF.  Additionally, MPS is right, this is fully documented so anyone should be able to find the reason for it.  Anyone with Java experience would not the use the features unless they were knowledgeable of their behaviors and even then a good developer would avoid them because they violate the law of least surprise.  I asked the IRC channel for an explanation because I am too lazy to dig through hundreds of pages of JVM documentation and pstorer answered my query accurately.  Once again, it's not like I would ever make use of these features, but I was curious as to why the existed.



  • @Eternal Density said:

    @morbiuswilters said:

    So, if it took you a couple of seconds to see the problem
    Unlike you, I am unable to read every word of the post simultaneously.  I'll agree that it's obvious what's going on upon reading.  It's nearly 4 years since I worked with Java and that was for a single semester of university.  Actually, Java was our (official) introduction to OOP, after a semester of C.

    Um, I meant if you saw Integer x = 3 you should know what that means.  Even if you aren't familiar with 1.5+ you should be aware of what Integer is and how it differs from int.  I've only had 2 semesters of Java and I skipped about 66% of my classes.  I never got a degree and I've done very little professional work in Java and it was still immediately apparent what was wrong.  Once again, I didn't understand why some examples seemed to work, but it wasn't confusing to me.  It's not like I see C code with uses of freed pointers and say "man, that's a total WTF that it works sometimes".  A basic familiarity with the language and with the kind of errors commonly made in software development should be enough to make you aware of the mistake instantly. 



  • @morbiuswilters said:

      Anyone with Java experience would not the use the features unless they were knowledgeable of their behaviors and even then a good developer would avoid them because they violate the law of least surprise.
    I agree.  But again, you do see a handful of Java developers complaining about autoboxing on the net, for what little that's worth.

    In fact, the following thread (which I only skimmed) almost seems like a mirror image of this thread.  At least, there are two sides, one of which is saying "autoboxing is confusing" and the other is saying "you aren't using it right, idiot!"

    http://www.theserverside.com/news/thread.tss?thread_id=27129

    EDIT: To be fair, that thread is 4 years old - it was obviously created right around the time that autoboxing was introduced in Java. 

    @morbiuswilters said:

    I asked the IRC channel for an explanation because I am too lazy to dig through hundreds of pages of JVM documentation and pstorer answered my query accurately. 
      Why are you still calling him "pstorer"?  Or are you actually not talking about bstorer?



  • @morbiuswilters said:

    Um, I meant if you saw Integer x = 3 you should know what that means.
    Yes.  Was that ever in question?@CodeSimian said:
      Why are you still calling him "pstorer"?
    I, too, wondered that.  Curently assuming it's for lols.



  • @CodeSimian said:

    I agree.  But again, you do see a handful of Java developers complaining about autoboxing on the net, for what little that's worth.

    In fact, the following thread (which I only skimmed) almost seems like a mirror image of this thread.  At least, there are two sides, one of which is saying "autoboxing is confusing" and the other is saying "you aren't using it right, idiot!"

    http://www.theserverside.com/news/thread.tss?thread_id=27129

    EDIT: To be fair, that thread is 4 years old - it was obviously created right around the time that autoboxing was introduced in Java.

    It may be confusing but it doesn't make the OP a WTF.  Java is a well-defined language.  It's not like C++ where even experienced devs can run into bizarre code snippets that are completely valid and correct but still senseless.

     

    @CodeSimian said:

    Why are you still calling him "pstorer"?  Or are you actually not talking about bstorer?

    pstorer is his real name.  I don't know how he makes that fancy, upside-down 'p' but I assume it's some sort of obscure Unicode character.  Seriously, ask him what his name is. 



  • @MasterPlanSoftware said:

    @CodeSimian said:

    to use Integer in all cases doesn not mean that the language features should not act sanely when you decide to use Integer. 
     

    When you understand how the primitives work and how the wrappers work it WILL make sense. 

    Anyone who would use == on a wrapper like Integer doesn't know what they are doing. I agree it would be nice to have a noob warning, but everything is working as expected/documented.

    Classic java programmer response. I've recently had the somewhat unpleasant experience of returning to Java programming after a few years in the C# / MS world. For all the faults of Microsoft the one thing that is nice is their expectation to assume that the programmer may be a n00b. In Java world, the community far to often takes a 'blame the programmer' approach.. Look everyone (says the Java expert) I understand how this works so why shouldn't you. Frankly its just not good enough.

    If you are going to put auto-boxing/unboxing into a language (and a good thing to do too - one of my main reasons to prefer C# as a syntax over java) then for heaven's sake people do it 'properly'. Properly means that if you have an Integer you can treat it as an int and vice versa *always*. In C# you just never, ever have to worry about this crap, but can still use/define instances of the unboxed Object reference types if you really want to. Where on earth did the java spec writers get this insane idea of having different behaviour between -127 and 127 and everywhere else? Maybe if the type was 'tinyInt' or something, but its an int people the range is between −32,768 and +32,768... please make it work the same throughout the whole range (or don't do it at all).

    Argh. What a nasty little wtf the 1.5 spec writers have blessed all you super-clever not-stupid-enough-to-get-confused-about-it-at-all java programmers with. Meanwhile C# programmers are saving their meat-space swapfile for important things like how the heck their algorithm fits together.



  • @Eternal Density said:

    I don't think it was.  It may not have become one if you hadn't assumed it was.
     

    @Eternal Density said:

    MPS, please believe that there are people in the world who have the capacity to start a thread without harbouring the intention to start a war.  I saw no such desire in the initial post.
     

    Ahhh to be young and naive again.



  • @utunga said:

    Classic java programmer response.
     

    Actually, had you chose to actually READ the thread you would see that from the start I have stated I am NOT a Java guy. I spend my days working in C#.

     

    Seriously, get off your white horse here. 



  • @utunga said:

    Clearly flamebait
    What the fuck are you bitches babbling about?



  • @Eternal Density said:

    @CodeSimian said:
    Why are you still calling him "pstorer"?
    I, too, wondered that. Curently assuming it's for lols.

    bstorer uses pstorer as his IRC handle, as Morbius was talking about getting information from IRC using the person's most common handle on IRC would be least confusing (especially since some of the IRC crowd hardly ever post in the forums, one not at all).



  • @Lingerance said:

    bstorer uses pstorer as his IRC handle, as Morbius was talking about getting information from IRC using the person's most common handle on IRC would be least confusing (especially since some of the IRC crowd hardly ever post in the forums, one not at all).
     

    Alright! Way to ruin a joke!



  • Every language has their querks you have to know about. The following is a similar c# mistake that can be made when boxing is not properly understood.

     

    bool Func1() //returns false

    {

       int one = 1; 

       object o1 = one;

       object o2 = one;

       return o1 == o2; 

    bool Func2() //returns true

    {

       int one = 1;

       int o1 = one;

       int o2 = one;

       return o1 == o2;

    The reason the first one returns false is that == is an operator overload that is executed depending on the static type of its operands. In c# == works exactly like it does in Java, unless it has been overloaded, that is when both the left and right hand operands are declared as object, their reference identity is compared.

    Boxing in c# occurs when you assign a value type to object (or to an interface type). In this case 1 is boxed twice and is given two seprate references. 



  • @subanark said:

    Every language has their querks you have to know about.
     

    These are not 'quirks'. These are expected behaviors. You cannot compare objects with the equality operators.

     

    Get over it, learn to use the language.

    Your new post is making you sound a bit like SpectateSwamp. I understand you are amazed by this behavior, but the rest of us actually understand this, and this is expected.



  • @MasterPlanSoftware said:

    These are not 'quirks'. These are expected behaviors. You cannot compare objects with the equality operators.

    Indeed, only loosely typed languages will have "sane" == operators. To those surprised please look at the following C:

    int main() {
    int a, b, *p, *q; //You can replace the pointers with wrapper classes as needed
    
    a = 5;
    b = 5;
    p = &a;
    q = &b;
    if (p == q) {
    puts("Hello World!");
    }
    
    return 0;
    }
    


  • @MasterPlanSoftware said:

    I understand you are amazed by this behavior, but the rest of us actually understand this, and this is expected.

     

    Naw..., I just want to point out that a lot of behavior with boxing leads to some unintutive behavior.

     

    My post is about boxing, and although it makes code more writable, it can lead to bugs, since this code "look fine".

     

    This has nothing to do with c, if we replace string with int, it works fine:

    bool func3() //returns true

       string s = "Hello";
       object o1 = s;
       object o2 = s;

       return o1 == o2;
     

     }

     



  • @Lingerance said:

    Indeed, only loosely typed languages will have "sane" == operators.

    This has nothing to do with static typing.  In your example, you are comparing memory addresses which behave quite sanely: you have two different addresses so obviously they are not equal, no matter what is contained within those addresses.  With objects, equality is more difficult because which members are relevent for comparison are dependent on the meaning of the object itself.  So the == operator only compares if the values are references to the exact same object -- pretty much the same thing as 2 pointers to the same address being equal.  It's not about the type system, though, it's about objects having their own comparison rules that aren't inherent to the language like numbers or strings are. 



  • @subanark said:

    I just want to point out that a lot of behavior with boxing leads to some unintutive behavior.
     

    All you are doing is pointing obvious, basic understandings.

    "Hey y'all did you guys know that a = a + 1 increments a variable, just like a++? Crazy huh?"
    @subanark said:

    it can lead to bugs, since this code "look fine".

    No, it really doesn't 'look fine'. At all. It is wrong.If someone is making this mistake, they have no idea what they are doing.

    @subanark said:

    if we replace string with int, it works fine

    You really just don't understand this at all do you?



  • @subanark said:

    Naw..., I just want to point out that a lot of behavior with boxing leads to some unintutive behavior.

    You should only have to be told that objects cannot be compared with == one time.  After that, it's as intuitive as using == to compare two numbers is.  You don't think non-programmers use symbols in that way, do you?

     

    @subanark said:

    My post is about boxing, and although it makes code more writable, it can lead to bugs, since this code "look fine".

    Seriously, WTF?  The code does not look correct.  It compiles, yes, so it works with the static system of types, but it's fucking wrong.  Anyone who knows how objects works knows this.

     

    @subanark said:

    This has nothing to do with c, if we replace string with int, it works fine:

    Does C# have the == overloaded for strings?  If so, that's just another rule you have to learn.  Java does not do this, but + is overloaded for concatentation and although it may be a tad inconsistent it's not the sort of thing that's going to give people aneurysms.



  •  @morbiuswilters said:

    Does C# have the == overloaded for strings? 

    String has quite a few overloads.

    http://en.csharp-online.net/CSharp_String_Theory%E2%80%94String_operators

    The fact that this surprises/confuses the OP is amazing. Perhaps he figured this out in between adding line numbers back into his program?



  • @MasterPlanSoftware said:

    String has quite a few overloads.

    http://en.csharp-online.net/CSharp_String_Theory%E2%80%94String_operators

    The fact that this surprises/confuses the OP is amazing. Perhaps he figured this out in between adding line numbers back into his program?

    LOL, "String Theory"...  Actually, that seems to be better than Java's limited overloading for strings.  string1.equals(string2) is a little annoying because a string is a primitive type that is easily, intuitively compared.  It's like languages that make you write num1.compare(num2)... blech..



  •  None of this is surprising to me, there are clear reasons why these operators behave the way they do.

    However, my primary point is:

    It is often accepted that performing the same operations on identical values will have identical results.

    In Java's case, Integer is assignable to an int value, but such assignment changes what == results in.

    In c#'s case, == is overloaded such that the static type of the object, not the value it contains, determins what logic is performed.

    Before Java 1.5, the only way performing the same operation on a value that was typed differently was to pass that value into an overloaded method. There are very few cases where more than 1 overload is valid for a paticular value, and even in those case, most of them act the same for the same value.

     The type of a value can be declared in a completly different location than where the value is used.

    E.g. if you asked someone what the value of c was given the code fragement:

    a = 1;

    b = 1;

    if(a == b) {

       c = 1;

    else  {

       c = 2;

    }

    The initial reaction is that c is 1, while the actual result (in c#) depends on what a and b are typed as. 



  • Seriously. You have worn out your point. You are beating a dead horse.

     

    You didn't have much of a point to begin with anyway. Let it die.



  • @MasterPlanSoftware said:

    You are beating a dead horse.

    Eat the horse and he won't be able to beat it anymore.


Log in to reply