4 ms·
Have you got a chance to read "Java Puzzlers: Traps, Pitfalls, and Corner Cases"? Java is a very surprising language with a lot of strange corner cases (a lot o
by 0xmarcin 4y ago
Have you got a chance to read "Java Puzzlers: Traps, Pitfalls, and Corner Cases"?
Java is a very surprising language with a lot of strange corner cases (a lot of them related to reified generics and wrapper types).
There is also a lot of magic going on in JVM e.g. there is one optimization that causes stack trace to be omitted if the exception is thrown from a given place a lot of times. Beginners then see an exception without a stack trace and are stuck. SO rel: https://stackoverflow.com/a/3010106/1779504 https://stackoverflow.com/a/3010106/1779504
Spring can be a source of confusing problems when defining beans (especially when you have to use Qualifier's). Most of the juniors that I had a change to work with had very hard time getting used to Spring bean model. And I am not mentioning here strange Spring Proxy behaviour that can defy even programmers with 10+ years of exp
- marginalia_nu 4y agoYeah. Generics is arguably Java's weakest point. They're an afterthought in the language's design and should in general probably be avoided in all but the most trivial cases. A lot of problems go away if you stop trying to make Java into Haskell or C++ and just avoid the feature unless absolutely necessary, which you rarely do. That said, I did once sorta port a somewhat tortured definition of Haskell's parser monads to Java's type system for an event at work, mostly as a joke. Like it's doable. Wouldn't want to maintain that code, but it's doable. In general I don't think "does it confuse beginners" is a great metric for what makes a good programming language. You'll be able to find a beginner who is confused by almost anything. Beginners are hopefully not the same people who will write or maintain the code.
- kaba0 4y agoWhile it is surely an afterthought, it is imo very well executed knowing that — while you can’t have proper Monads, quite a lot can be accomplished, just have a look at some FP libs written in Java.
- kaba0 4y agoI have read that book, and while it is a great read, it rarely employs realistic code you would run into (will you really cast some number literal multiple times and try to guess the resulting value in actual prod code? And things like that) I have yet to be bitten by this stack trace behavior, thanks for the heads up, but I think every platform has its idiosyncrasies. I would still not change it for UBs everywhere :D And I really don’t think that the spring model is all that difficult, we just have plenty of bad developers and not enough focus on proper education of juniors (often done by “senior”, bad devs)
- marginalia_nu 4y ago> I have read that book, and while it is a great read, it rarely employs realistic code you would run into (will you really cast some number literal multiple times and try to guess the resulting value in actual prod code? And things like that) There is some admittedly unintuitive behavior when it comes to type conversions, especially in bitwise operations. Like this is just nasty: long f(int a, byte b) { long ret = 0; ret |= b; ret |= (long) a << 8; return ret; } System.out.println(Long.toHexString(f(100, (byte) 64))); // 0x6440 System.out.println(Long.toHexString(f(100, (byte) 129))); // 0xffffffffffffff81 // you need to do long f(int a, byte b) { long ret = 0; ret |= Byte.toUnsignedLong(b); ret |= Integer.toUnsignedLong(a) << 8; return ret; }
- 0xmarcin 4y agoThe problem is that in Java byte is _signed_ type. So `(byte) 129` is the actual source of the problem, the number is simply out of range (-128 to 127). Since there is no byte literal and numbers by default are integers you always have to cast when calling a function with byte parameter. There is simply no distinction between safe and unsafe cast...