Jump to content

[Java] The woes of learning Java after years of C#.


Recommended Posts

Seeming as though Java is supposed to be a OOP-centric language, it is utterly terrible when it comes to handling objects. Some of even the most basic operations are either impossible, only available through reflection (which should be used as a last resort according to programming best practice), or horrendously long-winded and convoluted. There's no such thing as a delegate, or a predicate; their idea of lambda expressions is laughable; you can't even cast between a generic collection and an array of the same type! I've only been programming in Java for a week and already I despise it!

I don't mind writing my own helper or wrapper classes, so long as the basic tools are available to use them in an elegant way. Anonymous inner classes are ugly and pale in comparison to anonymous methods and block initialisers. The way they handle properties is ugly as well. I miss simple tools like typeof. Why don't ArrayLists come with a top-level iterator? Why can't overloaded methods have different return types? Why can't you cast between a generic list of a type and an array of the same type? Why can't you declare method signatures as types? Grr!

Silly Java!

*launches Visual Studio and breathes a sigh of relief*

Don't worry VS, I'll never leave you. I missed you so much!

Edited by ApacheTech Consultancy
Link to comment
Share on other sites

Oooh a Java rant, must be a programmer whose first language isn't Java (don't worry there are plenty of us around). Just so you don't start to think that you are on your own I will join in.

One of the most annoying things I find with Java is that there always seems to be a "Java" way of doing things that are already done in a standard way by most other languages. For example take building your project, make does a great job and is used for many languages and on many platforms. So how do you build a Java project, you use Ant. So there is a good reason for this? I have heard many different people try to justify it but as far as I can tell the only reason it exists is because some Java developer couldn't distinguish between tabs and spaces and so couldn't write a Makefile :). I have heard people claim that Ant is faster to compile the Java code because it only launches the Java compiler once, but really if starting your compiler impacts that much on a build then there is something wrong with the compiler or the way it is being used.

"At least it produces portable code." Is usually the next comment I hear. Really, I have lost count of the number of times that I have been trying to run a Java app only to find it complain that I am using to wrong JVM or runtime environment. Seriously , in my experience this portable language isn't very portable at all. I guess I have been spoilt by having scripts (Perl, Python, etc) run on both windows and *nix boxes without any complaints (Even a missing module is a simple case of installing just that module, not an entire new runtime environment which then has to be kept seperate from the other ones on the machine).

Now I must really stop ranting about Java, I will save the rest for the next time I am forced to deal with it at work.

Link to comment
Share on other sites

I've only used the very basic functions of it whilst developing the Duck Encoder v3.x on the USB Rubber Duck forum. My main problem is that I know in my head exactly how I would write the program in C#; exactly what would go where, how the different elements would fit together and the overall program flow. But, in Java, this would have to be split down into really convoluted segments.

Take, for example, the new Ducklings I've developed for v3. In C# you can use delegates to create a dictionary of methods which you can call dynamically without needing to use reflection or any convoluted anonymous inner classes. The Ducklings are designed for relatively new, if not first time coders to develop their own strongly-typed, secure plugins and distribute them across the community. Java's method of doing this took a day of research just to find out I couldn't do it as you would logically think of doing it in a high-level programming language and more time to implement a clumsy workaround. The v1 Ducklings are not as elegant as I would like them to be, they are still very clumsy and not amazingly easy to write for a first time user; hence the long detailed thread explaining their generation.

I'm not really sure about makefile and such, I've only used the basic "Right Click -> Export as Runnable JAR" in Eclipse. Because Java is a proprietary language owned by Sun, they govern what goes into it and what doesn't. Their excuses for why they have not introduced delegates is laughable; mainly because it would break anyone's code who has used workarounds for such things and called their variable "delegate". This is a pitiful excuse for not bringing out new coding structures; breaking issues are something that every developer expects to have to cope with and plans in advance to protect against.

Link to comment
Share on other sites

But that leaves a question; should a base programming language need an add-on framework just to be able to be usable? Java claims to be OOP-centric, then takes away (in its core syntax-base) the means to manipulate objects in elegant and straight-forward ways. Nested classes are an integral part of any OOP-centric language, but Java uses them in ways that they were never meant to be used; or at least in out-dated, now superseded ways which make the code clunky and inelegant.

I will have a look at the Scala pattern. I've seen Groovy as well, which does add in delegates in the form of Closures but they seem to be quite clunky as well and I haven't had time to look into the syntax patterns for it. Going into Groovy, or any other framework after only a week or two of learning Java is a daunting task. I want to learn the core, convoluted workarounds just so that I know how to use them. The same way you'd learn the intricacies of C# before using LINQ for everything.

Link to comment
Share on other sites

But that leaves a question; should a base programming language need an add-on framework just to be able to be usable? Java claims to be OOP-centric, then takes away (in its core syntax-base) the means to manipulate objects in elegant and straight-forward ways. Nested classes are an integral part of any OOP-centric language, but Java uses them in ways that they were never meant to be used; or at least in out-dated, now superseded ways which make the code clunky and inelegant.

First of all, Scala is not an "add-on framework". It is a distinct programming language which happens to compile to Java Bytecode so it can run in the Java Virtual Machine. The Java Virtual Machine (and its bytecode) is separate and distinct from the Java Programming Language. Obviously the two are related, but Scala is not an add-on. Scala targets the JVM in the same way Java (the programming language) targets the JVM. Or the same way that C# and VB# and F# and Nemerle all target the CLR (.Net's VM).

Second, yes Java is an OOP language. However Java's OOP model is NOT the same as C++'s OOP model. While Java's syntax is superficially similar to C++, it draws more from the influence of SmallTalk than it does from C++'s version of OOP. If you come at Java expecting it to behave like OOP in C++ then you're doing it wrong. I recommend reading Just Java 2 (http://www.amazon.com/Just-Java┬┐-2-6th-Edition/dp/0131482114/), it explains Java as a language from the perspective of one of the authors. It really gets you inside the mindset of Java's world view, explaining the design decisions that were made and what problems they were solving. No other book I've seen on Java really does it justice.

Java is not a perfect language, but it's not as awful as people tend to assume. The problem is that it tends to be poorly taught and poorly understood.

I will have a look at the Scala pattern. I've seen Groovy as well, which does add in delegates in the form of Closures but they seem to be quite clunky as well and I haven't had time to look into the syntax patterns for it. Going into Groovy, or any other framework after only a week or two of learning Java is a daunting task. I want to learn the core, convoluted workarounds just so that I know how to use them. The same way you'd learn the intricacies of C# before using LINQ for everything.

Again, Scala and Groovy are not frameworks, and they don't compile to Java code. They are distinct languages that happen to compile directly to Java Bytecode.

.Net languages like C#, VB#, Nemerle, and IronRuby compile to .Net Bytecode and run in the CLR.

JVM languages like Java, Scala, Groovy, Clojure, and Jython compile to Java Bytecode and run in the JVM.

There are other virtual machines out there, each with their own bytecode languages. (ParrotVM, NekoVM, BEAM, LLVM sort of)

Because Scala happens to share the same runtime environment as Java it is capable of calling libraries that were written in Java or any other language targeting the JVM. This is the same as VB# code calling a method that was written in C#. You don't need to learn Java first in order to learn Scala, in fact doing so would only serve to confuse you. While they share the same run-time environment, the have many different semantics and different approaches to solving the same problems. Scala also has features that Java currently doesn't (such as real lambdas, tail-call optimization, pattern matching, mixins, and more).

I like Scala because it's cleaner way to write code that can run on the JVM and interface with legacy applications or third-party code that was written in Java. It gives you all the benefits of the Java Platform and on top of that you get to write elegant code using Functional Programming paradigms.

You should still read Just Java 2, but just for the purpose of understanding Java's object model.

Edited by Sitwon
Link to comment
Share on other sites

Thank you for your comments. I will endeavour to get my head around a lot of the jargon. I've never really needed to look outside of .NET for anything. I've only used frameworks in WebDev, I take it the word means something different in AppDev. Eclipse does not make it easy to see the difference between Java and Groovy; if I'm honest I'm in way over my head with it. I'd just got to grips with the basics of Java when I found out they didn't provide the basic functions I needed to use as the foundation of the app I was making. I read into Groovy, it was publicised as an add-on for Java. I installed it on Eclipse, converted the project over and carried on coding just as you'd expect to be able to. Then I found out that Groovy isn't what I thought and doesn't even use the same syntax; yet, Eclipse didn't convert anything, it just changed the file name. For now though, I think I'll stick with C#; it suits my coding style a lot more and IMO, a much better and more powerful language to use. There's nothing I need Java for anyway apart from that on program, in which the clumsy Java workarounds will have to do.

Link to comment
Share on other sites

Java was my first language but after moving away from it to learn others I can relate to what you are saying, however, I still like to write in Java because it was my first language and I know it more fluently then I do others. With that said, python is by far my favorite language to write in.

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...
  • 3 weeks later...

I've heard of GTK in passing; from what I gather, it's .NET for Linux.

In that case, you can just code in .NET and make it Mac/Linux safe with the Mono Framework; an open source version of the .NET Framework.

Link to comment
Share on other sites

I've heard of GTK in passing; from what I gather, it's .NET for Linux.

In that case, you can just code in .NET and make it Mac/Linux safe with the Mono Framework; an open source version of the .NET Framework.

GTK+ is a cross-platform widget toolkit. It is used for creating GUIs. GTK+ is written in C, but provides bindings to many other languages including Java and C#.

By contrast, Java and .NET are fundamentally different. They are platforms which are composed of a runtime environment (VM), a set of standard libraries (which include a widget toolkit), and a default language (or languages) which are designed to make use of the standard library and target the runtime environment.

So when you talk about Java or .NET you're really referring to a full-stack platform that includes numerous discrete components (most of which can be swapped for alternatives) of which the widget toolkit for writing GUIs is just one small and relatively insignificant piece.

Link to comment
Share on other sites

  • 11 months later...

"At least it produces portable code." Is usually the next comment I hear. Really, I have lost count of the number of times that I have been trying to run a Java app only to find it complain that I am using to wrong JVM or runtime environment. Seriously , in my experience this portable language isn't very portable at all. I guess I have been spoilt by having scripts (Perl, Python, etc) run on both windows and *nix boxes without any complaints (Even a missing module is a simple case of installing just that module, not an entire new runtime environment which then has to be kept seperate from the other ones on the machine).

Keep your eyes peeled on the the Lazarus/FreePascal (Object Pascal) project, which is basically Delphi IDE open sourced! Lots of good stuff already and more goodies coming. You write once and compile EVERYWHERE. Not bytecode, but fast executables. Next major release allegedly will allow your code to run in JVM. Interesting times for coders indeed.

http://www.lazarus.freepascal.org/

Link to comment
Share on other sites

Keep your eyes peeled on the the Lazarus/FreePascal (Object Pascal) project, which is basically Delphi IDE open sourced! Lots of good stuff already and more goodies coming. You write once and compile EVERYWHERE. Not bytecode, but fast executables. Next major release allegedly will allow your code to run in JVM. Interesting times for coders indeed.

http://www.lazarus.freepascal.org/

Two things here...

1. Why Delphi/Pascal? Isn't that a dying language? What benefits does Pascal have over any other language?

2. Mature VMs actually tend to out-perform native compiled binaries. It seems counterintuitive, but a good just-in-time compiler (JIT) can optimize the code better than a static compiler because it can take into account actual run-time statistics and trends in the data which the static compiler has no ability to predict. That's how Facebook was able to make PHP fast enough to run one of the most sophisticated and heavily-trafficked web applications on the Internet. (See: HipHopVM)

Link to comment
Share on other sites

1. It is a dying language but it has its perks. The Turbo Pascal compiler was a worthy recipient of that name - it would run circles around anything around it. It also helped that Pascal was a structured language like C but easier to learn. I do believe that, at least originally, Pascal had a 255-byte limit on strings because the first character was used to indicate the length. This was fixed come Delphi, but even then only after a few versions. I know I'm swearing, but it's like VB: don't use it for everything - it's good at certain things and capable of a lot of other things but please, PLEASE don't go there.

2. My day job is in developing Java applications and my personal points of interest are performance and security. What you're saying here is 90% BS. Only in the most absolute of micro benchmarks can a JIT compiler approach and maybe surpass native code. In any sort of useful code it just doesn't compare. Consider Tomcat vs Apache httpd. Tomcat will lose every step of the way. Not by a lot, mind you. But it'll lose. You can tweak it to your hearts content, most probably fiddling with the garbage collector and the memory model but you end up doing some very, VERY insane things to get things to line up just right and get the proper cache behaviour. Google a bit for Multi Producer Single Consumer (MPSC) Queue Implementations to find some examples. There's a guy out there that can achieve insane performance, but he does it by padding the class, trying to align everything and ending up making things work perfect with his system and exactly that jvm version. It works, but it's so specific it's almost non-java.

Regarding the 10% that wasn't BS, yes Facebook replaced php with something resembling a JIT compiler which massively improved performance, but that example doesn't prove JIT is better than native, it proves that JIT is better than interpreted and if that's news to you then I can assure you you've been living under that rock for far too long now.

Link to comment
Share on other sites

Now you've done it...

NOW YOU'VE DONE IT!

I'm reading some chunks of this thread and as a developer (no, not a java-, C#-, C-, php-, perl-, ruby-, scala- or python-developer, although I'm at least capable in all of them) I'm getting a bit miffed by the misinformation spouted here. So because this is still the internet I'm going to stand on my little soap box and tell the world why they're wrong and feel better about myself, even though everybody will TL;DR. TOUGH!

Let's start with the build scripts. Supposedly you can't use a Makefile. Says who? A Makefile simply defines the order in which certain commands are run in order to produce your binary. You can use a Makefile with Java just as easily as you could use an ant script to build a c project. Certain tools catch on and become a de-facto standard (and since you started this thread in march 2013 you should've mentioned Maven instead of ant as it was, even then, the de-facto standard in java). Currently people are looking more at gradle and sbt. Both will work with anything, have some useful helpers for specific languages, but you're more than welcome to create some helpers of your own to support your pet language.

The next specific point of annoyance was delegates, predicates and lambda expressions. This is new in Java 8 and currently I'm not convinced I'll be making use of it anytime soon. Maybe I'm too big an idiot but I don't see the value of them. Ask again in a year or so.

Then comes reflection, being picked on for being "horrendously long-winded and convulted". I disagree. There are some long-winded and convulted ways of doing things with reflection that can't be done another way, but that's why you make a utility class and put that stuff well documented behind some method name that just says it all. It works that way in pretty much any OO language - write it once in a helper somewhere and let someone who dares to tread where there be dragons deal with that muck.

"You can't even cast between a generic collection and an array of the same type" - well, DUH! When you have, say, a TreeSet, something that implements the generic Collection type but comes with specific rules (no dupes and possibly no null allowed - behind the scenes it's actually a Map, but you said Collection and that's what this implements) and you cast that to an array, you're basically saying "Um, you know those rules that are dictated by that type? Yeah, well FUCK OFF AND GIVE ME YOUR OBJECTS, BITCH!" and you're surprised that it's not allowed? I'd consider any language that does allow such a redefinition without any warnings or some such rather broken.

"Don't worry, VS, I'll never leave you" Interesting quote. I'm sure I'm the only person on the planet to do this, but I program all my java stuff in vi. That's right, no IDE, no fancy schmanzy wizard that decides on my behalf what I want, NO! VI. It's all you need. Back in the Java 1 days I was still on Windows and I wrote my first java program using notepad. Can you write a C# program using notepad? Something a little bit more demanding than "hello world"? Of would you wind up knee-deep in XML-hell trying to figure out just what the hell the IDE is doing on your behalf with those files when you're programming? This is also why I hate Eclipse and Netbeans and the like. New recruits need to spend a solid hour or so to set up their IDE on a new machine just to be able to compile from their IDE with all the dependencies and tweaks and such. What a waste...

"Java isn't very portable at all" again I disagree but to a lesser degree. Your bog-standard java code will run anywhere where there's a JVM. There are a few packages of which you know that using them you're explicitly invoking methods in shared objects (dll on windows, .so on unix) and this, almost by definition, is non-portable. Steer clear of that and you should be golden. In all my years developing java programs I only ran into this issue ONCE and that was to get my program to interact with Word so that we could merge variables with a template and print it to a PDF. Printing on java SUCKS but, well, there you have it.

And while we're on the subject, shouldn't C# and its ilk be more portable? There's Mono but they're still quite some ways behind the current .NET spec. Why do you think that is? I'll let you in on a little secret: You know that P/Invoke thing that C# has, where it can call a system DLL method in a pretty much non-portable and potentially unsafe manner? The C# libraries are *PEPPERED* with the stuff. It's the only way they can manage to achieve the performance that they do. I'll happily admit that C# will mostly outperform Java even though I've never seen any proof of it. But when, say, JAXB came around (the library that can transform an object to XML and back again), you know what they had to do to integrate it into java and make it run everywhere? Nothing. Not a damned thing. Because it was standard java code that didn't try to play tricks with the system.

"Installing additional functionality is a pain" this is why maven came about and replaced ant - dependency declaration. Your maven build script (or pom-file) will declare that you use component X version Y. When you build and package your code, that one declaration will result in the build system discovering, downloading and including in your deliverable not only component X version Y, but everything it depends on, and everything those dependencies, in turn, depend on, ad infinitum. You wanted easy? That's easy.

"In C# you can use delegates to create a dictionary of methods which you can call dynamically without needing to use reflection or any convoluted anonymous inner classes." My first thought here is that you should;'ve used an Enum. I'd have to look at the ducky script to understand what, specifically, you'd want to do but wound up having to do instead.

About java not doing delegates using that word as a language feature: "This is a pitiful excuse for not bringing out new coding structures; breaking issues are something that every developer expects to have to cope with and plans in advance to protect against" Cool, and what's the weather like on your planet? Imagine the C language suddenly coming out and saying "list" is now a reserved language word. We own the language so you can just go and SUCK IT. What do you think will happen? A) developers around the world will go "Meh. I'll just replace the word 'list' with 'my_list_var' and be done with it", recompile and hope they got everything or B) Scream bloody, fucking MURDER hang the standards committee from their scrotum on the longest pole found on the globe and piss over the sharp spikes they planted at the base of that pole.

I'm putting my money on B, and will be sharpening my spikes the second I get wind of such an ill-conceived idea. You know why Windows took off as much as it did? Because Microsoft went out of their way (way way WAY out of their way) to ensure your wonky piece of bit-rotten junk whose mere compilation back in the 3.11 days was almost a crime in and of itself STILL ran under Windows XP. Did you notice the main reason why people are reluctant to move away from XP? It's because that funky piece of knitting pattern software the got distributed for free in a magazine 14 years ago DOESN'T RUN under Windows 7! Something that every developer expects my stinking ASS!

I think we'll leave it at this for now...

Link to comment
Share on other sites

Java does often fall short of C++ in real-world benchmarks, however not by a whole lot. It's biting at the heels of native-compiled C and C++ and still out-performs some native-compiled languages (eg, GNU Common Lisp). Compared to dynamic or interpreted languages, Java's performance is essentially equal to C or C++.

The small performance penalty of Java has more to do with the baggage of it's object model than it does with the optimization of the machine instructions. Java necessarily uses more bytes of memory to represent objects than is typical of the idiomatic C++ equivalent.

Regardless, Java is an old VM which still carries a lot of historical cruft. If you look closely at some of the optimization techniques of a more modern VM such as HipHopVM I think you'd be quite impressed with what can be accomplished, even compared to idiomatic C++.

As for Pascal... Pascal Strings were a terrible idea, as were several other "features" of the language. There has been a lot of valid criticism of Wirth's ideas over the intervening decades. Just as with VB, I'm struggle to see any valid use cases where it's the "right tool". Especially given all of the modern languages we have to choose from. I acknowledge that it is a capable language, but with so many better options why would you ever prefer it?

Just my opinion, I suppose.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...