13 ms·
Java: Missing Features
- lolklyn 11y agoWhat I would love to come over from C# is: * Auto-Properties - Get rid of all those ugle getters and setters cluttering up POJOs * Object and Collection Initialisers - https://msdn.microsoft.com/en-us/library/bb384062.aspx https://msdn.microsoft.com/en-us/library/bb384062.aspx
- mbfg 11y agomight want to checkout lombok. https://projectlombok.org/ https://projectlombok.org/
- kbenson 11y agoIsn't that just a boilerplate generator? I think the point is to have sane defaults and shorthand for common tasks so boilerplate generation isn't needed.
- dikaiosune 11y agoIf I'm not mistaken, Lombok generates the boilerplate at the bytecode level, not at the source code level. Which makes it much more like a language feature, and while I haven't used it extensively seems like a decent library solution to what is normally considered a language problem.
- nerdwaller 11y agoI just stumbled on this today (before coming here), looks really nice to rid some boilerplate. Regardless for some reason I still love Java...
- josecflk3 11y agoJust keep in mind that some of the features are a bit iffy. If you use their vals IntelliJ will syntax highlight it as an error in red for the simple reason that it's non-compliant with the Java language spec. Also, you'll usually need a new version on Lombok every time a new version of Java comes out, otherwise what used to compile with the previous java version will no longer compile. If you use the auto constructor you're going to have fun finding usages since there's nothing to click on, and changing the order of fields in your class will silently change the ordering of parameters in your constructor - double the fun of the fields are of the same type. You'll also be left wondering why you went to all the trouble of adding dodgy language extensions instead of just using a language which provides those features anyway. That and your code (subjectively) looks really ugly plastered with annotations everywhere. Some people like Lombok, just make sure it's a choice you make going in with your eyes open.
- jinst8gmi 11y agoTrue. I've seen multiple teams putting a lot of effort into removing Lombok from their codebases after all the trouble it caused.
- scalesolved 11y agoWe use Lombok heavily where I work, on > 5 projects and have yet to run into any problems like you describe. Everyone use IntelliJ apart from myself and haven't heard any issues with using 'val'. We started off just using it in tests but it's now spread throughout the code base, I can't imagine going back to pre Java 8 sans Lombok.
- ks 11y ago> If you use their vals IntelliJ will syntax highlight it as an error in red for the simple reason that it's non-compliant with the Java language spec. There's a free plugin that adds Lombok support to Intellij. You will be able to use getters/setters/builders etc. as if they were compiled.
- josecflk3 11y agoBuilders etc. work fine, it's the vals that are permanently underlined in red, even with the plug in. It compiles OK with vals, but still highlights it as an error in red in the editor.
- ionised 11y agoLombok's val is the only thing I don't use in the Lombok library.
- jonathankoren 11y agoIf there's no logic in the getter and setters, just make the properties public.
- ossreality 11y agoHuh? Then they're just fields and not properties, maybe I'm misunderstanding what you're trying to say. And there are numerous reasons that Properties are preferable to Fields. Unless someone else can help me, I think this is really bad advice for a C# developer.
- jonathankoren 11y ago>Huh? Then they're just fields and not properties Nomenclature schmomenclature. They're variables with object scope.
- jonathankoren 11y ago>Huh? Then they're just fields and not properties Nomenclature schmomenclature. They're variables with object scope.
- jonathankoren 11y ago>Huh? Then they're just fields and not properties Nomenclature schmomenclature. They're variables with object scope.
- Retra 11y agoThat works until you want to add logic without breaking existing interfaces.
- masklinn 11y agoOr until you need to use them in beans and the like.
- tajen 11y agoPlay!Framework 2 for Java is awesome in this matter. You write public members, but at compilation it transforms them into private members with getters and setters (if not final). It means if you write the setter, it overrides the default one.
- twic 11y agoSome of these, like reified generics, would be great, and it's sad it's too late to add them to the JVM. Some of these, like more expressive imports, seem pretty pointless given that we use IDE's. But some of these are quite un-Javaish. Structural typing would really go against the grain of the language, and i have a very hard time believing it would actually be useful. What method name is currently widely used with the same semantics across many classes, without being specified by an interface or base class? I can't think of one. There used to be close(), but that's been dealt with. Are there others? Collection literals seem like a poor idea when there are so many different collection implementations. If i say: List<Integer> list = {1, 2, 3}; What kind of list do i get? ArrayList, as that's the usual go-to? A foot-shooting opportunity for anyone doing concurrent programming! And a frustrating missed chance for anyone with a functional bent who would prefer an immutable list. Moreover, it seems unnecessary when you could easily just add constructors or factory methods like: List<Integer> list = new ArrayList(1, 2, 3); List<Integer> list = ArrayList.of(1, 2, 3); Which leave the choice in the hands of the programmer for only a minimum of extra syntax. Maps are a bit harder, because you need a way to describe pairs. In most projects i work on, i end up creating some helper methods that let me write: Map<String, Boolean> map = map(entry("Java", true), entry("Go", false)); And i wish there was a better syntax for that. Something like algebraic data types would be good, though. You can already implement un-extendable classes using mild hacks: public abstract class Shape { private Shape() {} public static class Circle { public static Circle of(int radius) { return new Circle(radius); } public final int radius; private Circle(int radius) { this.radius = radius; } } public static class Rectangle { public static Rectangle of(int width, int height) { return new Rectangle(width, height); } public final int width, height; private Rectangle(int width, int height) { this.width = width; this.height = height; } } } Because the constructors are all private, so putative subclass can't call them. But you don't get pattern matching, and of course it's all rather verbose. There are various madmen out on the edge of town trying to create terse approaches to this by meddling with forces beyond mortal knowledge: https://github.com/poetix/mtuples https://github.com/poetix/mtuples But i can't see that going mainstream.
- dajohnson89 11y agoI've been bitten by the "Long indices for arrays" lack once before. But then again, I had no reason for storing a String of length greater than MAX_INT in memory in the first place. Streaming it was the better approach in my case. Honest question: is there ever an acceptable case for having such a long String in memory?
- rdtsc 11y agoMaybe some large data structure in memory based on a flat array and indices underneath?
- andrew-lucker 11y agoSo would this affect all flat memory allocation? Say if you wanted to allocate 100GB for a bloom filter, would you need to break it into chunks?
- bad_user 11y agoYes, you'd need 6 arrays of 2147483648 longs (max int), plus one array of 536870912 longs, so a total of 7 arrays. Not that bad really.
- jerven 11y agoYes, I have code like that and its annoying and bug prone. Even if its a write one exercise :( Would be nice if could just avoid that exercise in bit shifting and anding.
- deleted 11y ago[deleted]
- nurettin 11y ago>For example, it was only with C++14 that lambda expressions finally arrived. nope.
- i_s 11y ago> The issue of primitive specialisation of generics is only tangentially related to type erasure, and run-time visible generics are actually much less useful than Java folk wisdom insists. Run-time visible generics are pretty important because it lets us avoid boxing everything. In .NET, they don't have this problem, and as a result primitive dictionaries are ~17x faster [0]. Java folk wisdom seems pretty accurate to me in this case. [0] - http://fsharpnews.blogspot.com/2010/05/java-vs-f.html http://fsharpnews.blogspot.com/2010/05/java-vs-f.html
- bad_user 11y agoHe's talking about reification versus specialization. The .NET runtime is specializing generics for value types and that's how you avoid boxing. For normal classes though, specialization would not have any benefit and the boxing argument goes away. Interestingly, specialization can be done at compile-time and doesn't necessarily have to be a runtime feature. Here's a Scala compiler plugin doing that: http://scala-miniboxing.org/ http://scala-miniboxing.org/
- masklinn 11y ago> He's talking about reification versus specialization. It's neither according to the usual (C++-inherited) lingo where specialisation is the userland override of generics reification. Refinement may be a better term for what the article is talking about (runtime-optimised instances without reified types). And refinements should already be doable in java today with no static type information, Pypy does it with list strategies, I expect Objective-C's hidden classes could also enable it (though I'm not aware of such a use). > Interestingly, specialization can be done at compile-time That's where they started...
- hahainternet 11y agoDid you read any of the comments? I did and I am certainly not qualified enough to know if the 17x faster claim holds up at all.
- i_s 11y ago
- incepted 11y agoThe author of the article seems to be essentially looking for Kotlin (except for the structural typing part, which is a terrible idea and which Kotin thankfully ignored).
- jinst8gmi 11y agoStructural typing is actually very useful when you need it occasionally, which is one of the reasons I've largely ignored Kotlin so far. The jury is still out on that one.
- alkonaut 11y agoApart from primitive specialization the biggest omission in my opinion is the lack of value types ("structs"). It's almost impossible to write code that is heap allocation free or allows reasoning about cache locality.
- jahewson 11y agoIf you're familiar with the JVM's "escape analysis" then it is at least possible to write allocation-free code. But keeping a mental model of the JIT's optimizer in your head does not make for fun or easy programming. It's so much nicer to work with value types such as those found in C#.
- vrotaru 11y agoJust yesterday I've watched this: https://www.youtube.com/watch?v=88-szpeNfrU https://www.youtube.com/watch?v=88-szpeNfrU Long story short: keep the traditional getters and setters but have just a byte[] field to store the object state. For example If you need just the date (without the time) you can store it in 2 bytes, say 7 and 8, and in getDate() method you do public Date getDate() { int day = bytes[8] * 256 + bytes[9] return new Date(day * MILLIS_PER_DAY); } Some of the improvements are amazing
- jerven 11y agohttp://objectlayout.org/ http://objectlayout.org/ is a possible solution. But currently it and panama and JEP 169 are still forming into a hopefully coherent gestalt :(
- ww520 11y agoThings that would be good to add in Java are: - Collection and map literal. - Value type. - Multiple return values. - Destructure. - Pattern matching.
- saiya-jin 11y agothat multiple return values got me interested. I can see this exploding complexity/unreadability of the code at first glance. honest question - what would be real added value compared to dedicated wrapper type holding all you need for return?
- jinst8gmi 11y ago1. Not having to declare a pointless wrapper class. 2. Tuples support pattern matching. 3. For simple cases the return type is clearer, no need to dig up another class declartion to figure out what the field types are.
- ww520 11y agoIt actually makes the code concise and clearer. e.g. (int, float, float) calcPosition(...) { ... return (type, x, y); } var (type, x, y) = calcPosition(...); if (type) move(x, y); or var (int type, float x, float y) = calcPosition(...); I would prefer the first case with automatic type inference.
- runT1ME 11y agoOk weird, as a scala programmer these aren't the main pain points when I go to a less powerful language. I miss monadic comprehension, implicit parameters/higher kinded types (for type classes) and inference the most.
- logn 11y agoI would like to see support for json and regex, similar to JavaScript.
- pjmlp 11y agoSome of those missing features are being worked on for Java 10 and can be tested already from the early prototype that is available. JVMLS 2015: https://www.youtube.com/playlist?list=PLX8CzqL3ArzUo2dtMurvpUTAaujPMeuuU https://www.youtube.com/playlist?list=PLX8CzqL3ArzUo2dtMurvp... Technical Keynote at JavaOne 2015 https://www.oracle.com/javaone/on-demand/index.html https://www.oracle.com/javaone/on-demand/index.html Of course, first we still need to get Java 9. And then when Java 10 with value types, reiffed generics, new FFI API, long Arrays is available, one can write blog posts about being forced to use Java 7 with these missing features on Android.
- deanCommie 11y agoMoving from C# to Java 3 years ago was a painful experience in language expression. However, IntelliJ, Java8 Streams, and Google Guava made the process tolerable. I've grown to begrudgingly tolerate the weak Generics support, but the one thing absolutely still drives me insane is that I cannot have a method overload for a different generic parameter i.e. public void do(List<ABC> abcs); public void do(List<DEF> defs); FFS Java, come on. (Yes, I know, type erasure, it's still humiliating)