5 ms·
Java is crufty, but it's the best general purpose language I know. There's hardly anything you can't build in Java. "Casual" Java programmers usually miss the
by thermodynthrway 8y ago
Java is crufty, but it's the best general purpose language I know. There's hardly anything you can't build in Java.
"Casual" Java programmers usually miss the most important feature, what really makes it possible to do almost anything in Java. Reflection and runtime code generation. Every time I look at Go this ends up being a problem, worse than lack of generics. A lot of Java libraries use these features under the hood to make things like JPA and JSON serialization work.
Nothing I'm aware of comes close to Java in this, where you can redefine the language and rewrite compiled code at runtime while still maintaining execution and memory safety. Java agents, annotation processors, and libraries like JavaAssist, ByteBuddy, and ASM make seemingly impossible things pretty easy to write.
This is why annotations are used for everything in Java. They're often just tags used to find targets for rewriting code at runtime.
I was trying to write a thin ORM for Go and quickly found out it was impossible to do what I needed without blowing a bunch of nasty generated source files into the build. In Java, I can give the developer a nice clean interface and just generate the code when the app starts. Go forces you to expose all this to the user of your library
- badrabbit 8y agoI think it's the crappy jvm's that keep giving java a bad name. If only you could compile native executables independent of a runtime/jit/bytecode. On the contrary java has been around since 1994. Who knows how mature golang and python will get after aging and maturing like java.
- cordite 8y agoNative images are getting more attention, but they give up a lot of this runtime magic.
- ivan_gammel 8y agoPython is older than Java.
- thermodynthrway 8y agoThe JVM is a double edge sword. It makes all of this possible. Not only can you generate code at runtime, Java will optimize it just as well as if it was originally compiled in the application. I'm not sure why people harp on the JVM so much. JavaScript uses a runtime with even more magic that uses 5-10x as much RAM. I think the crappy JVM's of the past along with bad memories of Java Applets tarnishes its reputation unfairly
- innagadadavida 8y agoA major pain point with JVM even today is the startup time. This is especially true for command line tools. I use hdfs tools and it is really slow to start. Someone wrote a Go replacement that is 100X faster to start. None of the JVM sophistication means anything if it cannot solve simple common world problems. The java community has failed in this regard in my opinion. [1] https://github.com/colinmarc/hdfs https://github.com/colinmarc/hdfs
- thermodynthrway 8y agoThis is actually being addressed, eventually. There's work being done to lower the startup time in Java 9-10 but I'm not sure what state it's in. Basically cache everything from the first run to make future launches almost instant
- ptx 8y agoI played around a bit with that, i.e. app class-data sharing and AOT compilation. It turns out Java 9 comes with an enormous regression in launch performance, so that even with app CDS enabled it is slower than Java 8 to start. Java 10 is slightly better but still slower than Java 8 by default. Enabling app CDS gets you back to comparable performance to Java 8. With AOT enabled (in addition to app CDS) it might be faster, but that just crashes on machine (and only works on Linux anyway). So don't get your hopes up too much.
- sreque 8y agoTotally agreed that java fails hard for use cases involving small, lightweight binaries that are low memory and fast to start. This is an area where golang shines on the other. People are starting to experiment with AOT compilation via graal to make headroom in this space, but the techonology being used feels young, nascent, and experimental or immature: https://medium.com/graalvm/instant-netty-startup-using-graalvm-native-image-generation-ed6f14ff7692 https://medium.com/graalvm/instant-netty-startup-using-graal... https://www.innoq.com/en/blog/native-clojure-and-graalvm/ https://www.innoq.com/en/blog/native-clojure-and-graalvm/ Interestingly most high-level runtimes also have slow startup, including python, ruby, and node.js, but java's feels worse because people seem to want to use heavyweight frameworks like spring or aspectj that absolutely murder startup time, that for instance generate bytecode on startup or use classpath scanning to discover dependencies.
- pjmlp 8y agoYou can since around Java 1.2 time actually, the problem is that most devs don't want to pay for commercial tools. Almost all third party commercial JDKs have some form of AOT support.
- StaticRedux 8y ago> Nothing I'm aware of comes close to Java in this, C#. No Type Erasure. More powerful reflection with less code. Not to mention the unbelievable power of Roslyn and being able to programmatically generate code with little effort. If you love Java reflection, your mind will be blown by C#'s.
- thermodynthrway 8y agoI came from the C# world :). And yes, it's even more powerful, plus reified generics. The huge problem is that it's not that much better than Java which has ~50X more open source software written for it. The day MS makes a bytecode transpiler so I can use my Java libraries in C# I'll never touch Java again. The languages are so similar I have no idea why they haven't done it yet
- wpdev_63 8y ago"The huge problem is that it's not that much better than Java" I always see the .net fanboys tout how much better C# is than Java with generics, await/async, etc. but at the end of the day it's not that much better when you can achieve the same thing in Java with better open source support and across oses. I know there's .net core now but I am not going near it until it matures.
- thermodynthrway 8y agoI miss all that from C#, some of it a lot. But Java has a community so large that they've basically hacked these things into Java anyways. LINQ -> streams, QueryDSL, RxJava, JOOQ etc Async/await -> Comsat/Quasar The type system is lightyears better in C# but it was rare that I needed those features. Usually you can hack around the limitations and end up with something (slightly cruftier) that does the same thing in Java. Mockito, Retrofit, and RxJava are good examples of hacking about the type system until you have something good enough. That said, there are definitely times I still miss C#'s stellar type system. Easily the best of any language I've touched besides maybe Typescript (which is designed by the same guy)
- vardump 8y ago> There's hardly anything you can't build in Java. I do bare metal/low level embedded, kernel drivers, and occasionally shared libraries. Java is useless for practically all of my typical use cases.
- calgaryeng 8y agoYour comment seems largely unnecessary.
- guitarbill 8y agoI get the sense you're being contrarian. Op isn't saying it's the best choice, but being in that field, you should know that even those things people have tried to do and sometimes done with Java. For example, Java-based smart cards or Java Micro Edition.
- repolfx 8y agoTechnically speaking you can build these things in Java. JNode is an OS written entirely in Java, including the drivers. You probably meant "drivers for linux/windows" though and yes, there it's not so useful. You can also make shared libraries with Java these days. Look at SubstrateVM. It turns Java code into a .so file that doesn't depend on the JVM, compiled ahead of time, with a C API exported.
- vardump 8y agoYes, there's very little in software development that's strictly impossible. Practicality is another matter. > Look at SubstrateVM. It turns Java code into a .so file that doesn't depend on the JVM, compiled ahead of time, with a C API exported. Thanks, will do. I've been mostly eyeing Webassembly for some "cross-platform shared object" use cases.
- pjmlp 8y agoThese guys think otherwise https://www.ptc.com/en/products/developer-tools/perc https://www.ptc.com/en/products/developer-tools/perc https://www.aicas.com/cms/ https://www.aicas.com/cms/ http://fiji-systems.com/ http://fiji-systems.com/ https://developer.android.com/things/ https://developer.android.com/things/ Of course it isn't suited when trying to fit something into PIC with 64KB.
- alfalfasprout 8y agoIt's really a matter of preference, but Go encourages you to expose more to the user. It tends to discourage heavy abstraction. You don't really need runtime code gen (Go actually does have reflection) and it's certainly quite possible to write clean implementations of most things without it. Java's real issues like in two aspects: 1) Bad Java programmers have built a culture of writing "overpatterned" enterprise code (with FactoryBuilderFactorFunctions) 2) Horrible GC/iffy performance for a modern language #1 is reason enough to avoid Java like the plague. #2 makes it totally unsuitable for heavy numerical computation or systems level applications. Nothing like huge GC spikes to liven up your day.
- KennyCason 8y ago1) I mildlt disagree with this. There are lots of amazingly written Java libraries, and not all teams or people write “over enterprises code. I’ve seen dubious code quality on both ends of the spectrum in many languages. I do not think this is limited to Java, but more of a fact that Java is very popular and has been around for a long time, and thus has a lot of both good and bad history with it. I feel that modern Java practices have really improved. 2) Without a doubt native shines here. I’ve also been a victim of those massive GC spikes in the past. But I think saying the JVM has horrible GC seems a bit hyperbolic as it’s quite matured and more than adequate for most usecases.
- drbojingle 8y agoReflection? Lisp dude
- sjellis 8y ago> I was trying to write a thin ORM for Go and quickly found out it was impossible to do what I needed without blowing a bunch of nasty generated source files into the build. In Java, I can give the developer a nice clean interface and just generate the code when the app starts. Go forces you to expose all this to the user of your library Speaking as someone moving from Ruby to Go, I actually like the strong stance that Go takes against magic. The original article acknowledges that Go works the way that it does by design, and acknowledges the reason very fairly: the language is firmly on the side of making code easy to read, even at the expense of making it less elegant to write.
- beagle3 8y agoThe biggest problem with Java is the culture. All modern languages are Turing complete and roughly equivalent in the their expressiveness (Lisp, APL and Forth notwithstanding). But only Java people seems to have an AbstractAbstractFactoryFactoryWidgetGadget fetish. When I have to do Java, I keep recalling Brazil[0]. [0] https://www.imdb.com/title/tt0088846/ https://www.imdb.com/title/tt0088846/
- icedchai 8y agoMore modern Java libraries and frameworks don't have this issue. Sure, if you look at JEE stuff, you'll run into it...
- captainbland 8y agoI think you're right, but for me Java lacks compile-time features sorely (JavaPoet looks alright, but suffers from not being an official component of the JDK). Thinking about the user I'd much rather have that processing done at compile-time than startup-time. I guess this is part of where the appeal of Scala and Clojure lies. Rust and Nim provide the sort of thing I mean, hygienic macros - they're nicer than reflection because you keep type safety and you keep run-time performance without generating a bunch of transient source files. Nim's also got a nice RTTI interface, too.