Java vs C# for Java newbies



  • My team is made up of C# devs. We've all (except me - I've worked with all sorts of shit) been only C# Enterprise devs.

    Our company in its wisdom has given us a major Java project, covering a couple of RESTful webservices, consuming a RabbitMQ queue, Java services and a whole load more. We'll be using Spring as that is the company standard. And MongoDB as that is the latest buzzword.

    As pretty decent C# devs I do not doubt that we can segue into Java. However, the thing that does worry me is that none of us has ever actually done any Java (aside, again, from me, I've played with Android dev)

    Therefore: please tell me what I should be wary of; what gotchas might bite us on the arse and what other advice you cross-platform guys might have.

    [I would have posted this in the Coding Related Help & Questions category; however the "New Topic" button is disabled there]


  • ♿ (Parody)

    @scudsucker said:

    [I would have posted this in the Coding Related Help & Questions category; however the "New Topic" button is disabled there]

    That's the old CS category. We have a General Help -> Coding Help subcategory.



  • Fuck. Well, I doubt that the "topic" can be moved, so I guess it will stay here.



  • @scudsucker said:

    what gotchas might bite us on the arse

    I'll go for the simplest ones which always causes Fun:
    Generic type erasure: List<String> isn't a list of strings; It's a list of objects that the compiler will automatically insert casts on.
    The code:

    List<String> strings = getStrings();
    String first = strings.get(0);
    System.out.println(first);
    

    is equivalent to:

    List strings = getStrings();
    String first = (String) strings.get(0);
    System.out.println(first);
    

    This causes issues not just in regular code, but also with Spring versions < 4, as it is unable to see a difference between Product<Foo> and Product<Bar>.
    I've seen Spring give a Product<Bar> instead of a Product<Foo>, for instance, and everything works just fine until much later on when you get a ClassCastException.

    Another simple but annoying one:
    Unless you're dealing with primitive types, == compares that two object references refer to the same instance, similar to comparing pointer addresses in C.
    E.G. "hello" == "HELLO".toLowerCase() is false


  • Notification Spam Recipient

    If you're pulling collections for the keysets,valuesets or entrysets out of a HashMap remember that you can never guarantee the order of those collections ever. If you need to maintain insertion order use a LinkedHashMap or if you need to specify a particular order use a TreeMap and supply a comparator.

    Also remember removing or inserting items into those collections will do unseemly things to the hashmap they're pulled from.

    I've cleaned up variations of this nonsense at least seven times this year and I suspect I'll be doing the same for years to come.



  • OK. So heavy on the unit testing then. Thanks.



  • There are very very very few cases where MongoDB is an appropriate choice. Were you involved in that decision?

    Unless you're making something like Twitter, it's probably not what you want... and if you are making something like Twitter, there's still better options out there.



  • So Mongo was the buzzword about 2 years ago. I'm in the 3rd world (South Africa) and we are always a couple of years behind.

    I've never used Mongo; I don't know the typical use-case, although I'd assume a large-scale, performant system with little in the way of relational data. We are building such a system, although "large scale" perhaps doesn't count. (+/- 5 million users, max - at a wild guess - 20 000 concurrent app users during a large event)

    While I don't want to explain it too much, my parent company has numerous phone apps for subsidiaries. Our task is to set up a generic, company wide system to allow the various marketing people to set up a system to send push notifications. There are a lot of business rules around who can get what notification so we need to keep track of them, and log what got sent to who. The format of the notifications will also differ massively - and as we are sending notifications as JSON why not store them, in a DB, in a similar format.

    To me that sounds like it could either way, either a traditional RDBMS or a document store. We don't need high speed CRUD (we'll be reading off a message queue to actually send)

    Mongo was chosen by our Architect - I can easily argue with him about it if I have sufficient reason. Except I nothing about it, aside from very limited research. Its currently the buzzword at my company, but I do not know what specifically is bad about it.



  • Well a lot of my MongoDB knowledge is out-of-date, so it might be better now.

    MongoDB used to consider a record "securely stored" if it was in a network packet waiting to get sent to a replication server. Which is fine if your MongoDB is just a single server, but if you're not going to do replication you might as well just use something more reliable and proven.

    MongoDB was hot shit a few years ago, then the tables kind of turned in the other direction. It's still fine for creating an application where losing a few records isn't a big deal (example: Twitter), but if you need:

    @scudsucker said:

    There are a lot of business rules around who can get what notification so we need to keep track of them, and log what got sent to who.

    then you need to take a long, hard look at it.

    Also:

    @scudsucker said:

    The format of the notifications will also differ massively - and as we are sending notifications as JSON why not store them, in a DB, in a similar format.

    be sure to take a long, hard look at MongoDB document size limits. Currently it's 16 MB. That's pretty tiny. It might go up in the future, but I wouldn't build a product based on that hope.

    One thing I'll say for MongoDB, not that this helps you, but its C# driver is amazingly complete and bug-free.



  • OK. Quick bit of research later. (a random high-ranked article)

    The best argument for a document store is that each entity is independent and not related to another.

    The best argument for an RDBMS is that entities are shared and have relations.

    I guess we'll be using Postgress or MySQL then,as we care about Users, their Notifications, NotificationType, etc etc. Very much relational.


  • :belt_onion:

    @Salamander said:

    This causes issues not just in regular code, but also with Spring versions < 4, as it is unable to see a difference between Product<Foo> and Product<Bar>.I've seen Spring give a Product<Bar> instead of a Product<Foo>, for instance, and everything works just fine until much later on when you get a ClassCastException.

    That's not entirely true - It won't usually cause issues in code (unless getStrings() returns List or List<Object>. Even in that case, you'll get a compiler warning (unchecked cast) when you do that. It still type-checks that lists are lists of the same type or have a superclass of the same type. You'll only run in to issues if you're using something legacy that doesn't do that (written before generics is the usual cause) or if you do stupid crap casting things.

    Spring very well may not play nicely with those though.



  • Further research, from a link in the "is Mongo for Me" thread/topic says a very firm NO to MongoDB



  • It occurs in code which uses reflection, which I've unfortunately seen a fair bit of lately.


  • Trolleybus Mechanic

    However long you think it will take you to do something, triple it. Because you won't have the luxury of a sane or usable IDE. It'll crash. It won't have any tools in any place you expect them. Whatever hobbled Intelli-sense they've hacked into it won't work half the time. Chances are it'll fall down hard when you try to start the debugger.

    Then take that time and double it again-- because developing in Java means you'll need the JDE which means you'll end up getting the JRE at some point which will silently install itself into all your browsers which will open a massive attack vector. You'll get malware at least once, and it will wipe out some poor dev's machine. They'll lose their work. Make sure you have regular backups.



  • @Salamander said:

    Unless you're dealing with primitive types, == compares that two object references refer to the same instance, similar to comparing pointer addresses in C.E.G. "hello" == "HELLO".toLowerCase() is false

    Interesting. They don't have string caching, like in C# and pretty much any other language?

    "a" == "a";
    // true
    
    "a" == "A".toLowerCase()
    // false
    

    I... I don't understand.



  • Not exactly, no. They have string.intern() which fetches an equivalent string from a shared pool (or puts it in there and returns itself), however you need to manually call it on any strings you create.
    String literals are always interned by default, which is why you get the weird behaviour in your snippet.


  • :belt_onion:

    So... I know this is a 🚎.. But...

    IntelliJ is honestly the best IDE I've used in my time developing. I can't really speak to the other Java IDEs but I've been thoroughly impressed by IntelliJ. The only downside is that (especially on startup) it can get a little sluggish and it can be a little slow on handling huge files.

    The JDK isn't that bad to deal with - just disable java in your browsers, keep the shitty updater turned off, and use apt-get or chocolatey to update it.



  • Gotchas/irritations I've come across as a primarily C# dev.

    1. Classes in Java are virtual by default.
    2. Java doesn't use the IInterface convention so List<String> is IList<String> in C# speak.
    3. Classpath hell
    4. Classpath hell
    5. Classpath hell
    6. Maven vs Ant
    7. Classpath hell

  • Trolleybus Mechanic

    @sloosecannon said:

    So... I know this is a 🚎.. But...

    No. It really isn't.

    @sloosecannon said:

    IntelliJ is honestly the best IDE I've used in my time developing. I can't really speak to the other IDEs but I've been thoroughly impressed by IntelliJ.

    That may be the issue. You've never used Visual Studio. It's like saying "Of all the cars I've driven (a beige Camary and a rusty pinto), the Camary is the best". Then someone pointing out that maybe you'd enjoy driving a car with, like, power steering and working brakes.


  • :belt_onion:

    I... Have... Used Visual Studio. 2010, 2012, 2013, and 2015. I prefer Intellij.


  • Trolleybus Mechanic

    @sloosecannon said:

    I... Have... Used Visual Studio. 2010, 2012, 2013, and 2015. I prefer Intellij.

    TIL: Intellij causes massive brain trauma.


  • :belt_onion:

    TIL: You've either never used it or can't accept that someone's preferences may be different.

    I didn't say I disliked VS - I actually like it a lot. But I like IntelliJ more.

    Filed Under: Jesus, it's not like it's a religion or something


  • :belt_onion:

    To elaborate:

    I prefer the way IntelliJ does its autocomplete/IntelliSense. I like the small features it provides like postfix completion. I like the potential error detection features. It feels more complete and better than Visual Studio, personally.

    YMMV. Consult with your doctor before switching development environments. Take each opinion with a grain of salt. Do not taunt happy IDE ball, etc.



  • @Salamander said:

    E.G. "hello" == "HELLO".toLowerCase() is false

    Oh christ. That's horrible.



  • In addition to what @Salamander said, == is always a reference comparison on object types... including String.

    Besides which, Java's String has an .equalsIgnoreCase, so why aren't you using it?


  • Trolleybus Mechanic

    @sloosecannon said:

    TIL: You've either never used it or can't accept that someone's preferences may be different.

    TIL: You're mentally incapable of imagining a world where both of those are true.


  • :belt_onion:

    OK. Whatever ya say. Nice ad hominem by the way.


  • :belt_onion:

    Hmm, yeah, I guess that makes sense. Sorry to hear that :(


  • Trolleybus Mechanic

    @sloosecannon said:

    OK. Whatever ya say. Nice ad hominem by the way.

    You might want to re-read the words before you go full Fox.


  • :belt_onion:

    o.O

    I'd take the implication that I have "massive brain trauma" as an ad hominem attack, wouldn't you?

    I guess Java pissed in your cheerios at some point or something.. I mean, I don't really care much for the language (or any language, really), and Oracle can die in a hole, but I think your original post was a little over the top. IntelliJ is an excellent IDE, and I really don't get why you seem to dislike it so much. And yeah, the Java install is a pretty nasty :wtf:, but using the offline installers and something like Chocolatey or Ninite makes that process much less painful. Java isn't even a malware vector if you don't have the plugin enabled (which I don't, because screw people with Java applets).

    Criticize it for its faults as much as you want, but that original post was much more exaggerated than reality.



  • You're definitely going to want to use ether Maven or Gradle to manage dependencies in your projects. There is a learning curve for either one... but most Java editors (such as Eclipse) have plugins to read Maven or Gradle projects and import the proper dependencies.

    The Maven Central repository is the closest thing Java has to .NET's NuGet. Despite its name, Maven Central is accessible from both Maven and Gradle.

    Since you're dealing with REST WebServices, you may want to read up on JAX-RS, which is the J2EE Rest Webservices standard. I generally try to stick to J2EE standards unless I'm dealing with something non-standard. That way, if I find out that JAX-RS implementation #1 (Jersey is the reference implementation) is buggy, I can switch over to implementation #2 (such as JBoss's RESTeasy).

    Having said that, the Spring MVC framework can handle REST requests directly using the @RestController annotation instead of the @Controller annotation on the class. You may also need to specify in the @RequestMapping that it produces MediaType.APPLICATION_JSON_VALUE

    As a general rule, the Maven Central repository has separate entries for a specification and its implementations. In Maven, if you're coding against the spec instead of the implementation, you generally want the spec as a compile dependency and the implementation as a runtime dependency. With Gradle, you don't have a choice as it doesn't have the concept of runtime dependencies.



  • @scudsucker said:

    The best argument for an RDBMS is that entities are shared and have relations.

    ... and ACID compliance, and 40+ years of research, and a market of experienced people who are knowledgeable in writing performant applications...


  • Trolleybus Mechanic

    @sloosecannon said:

    I'd take the implication that I have "massive brain trauma" as an ad hominem attack, wouldn't you?

    No. Saying "This retarded money used a Java-based app to rate the taste-- therefore Java is a bad language" would be an ad-hominim.

    What you said:
    TIL: You've either never used it or can't accept that someone's preferences may be different.

    What I said:
    TIL: You're mentally incapable of imagining a world where both of those are true.

    Translation:
    I'm exasperated that you, sloosecannon, aren't capable of imagining a scenario where me, Lorne Kates, am wrong in two ways at the same time.

    So my conclusion is that your humor center is broken. It must have been from all the brain damage using a Java IDE caused you.



  • @Lorne_Kates said:

    a beige Camary

    I'm having trouble parsing this. Would you be referring to this...

    Or this?


  • Trolleybus Mechanic

    Camry.

    If I was talking abut Camaro, my sentence would have included the words "bag" and "douche", but in a different order.


  • :belt_onion:

    aw belgium. I'm sorry, it's been a long day.

    I still think your first post was a little harsh, but apparently that was a massive whoosh.



  • @Lorne_Kates said:

    If I was talking abut Camaro, my sentence would have included the words "bag" and "douche", but in a different order.

    You sound quite ungrateful for all the business that the previous generation of that car generated for you guys!



  • @Lorne_Kates said:

    That may be the issue. You've never used Visual Studio. It's like saying "Of all the cars I've driven (a beige Camary and a rusty pinto), the Camary is the best". Then someone pointing out that maybe you'd enjoy driving a car with, like, power steering and working brakes.

    I used Visual Studio, and now I'm working in JetBrains tools (not Intellij, but similar).

    There are things I miss when I go back into Visual Studio. If you're working outside of C# world (javascript, html, etc.), I'd say JetBrains IDE-s are better at this point. Not sure about java, though.



  • I was a PHP nerd before this C#/Java job, so I've used IntelliJ Idea. It is excellent, second only to Visual Studio with Resharper.

    That said, it is not hard to beat running Eclipse (or Eclipse-based things) on Windows which is the alternative Java IDE available to us. The last time I tried that (FlashDevelop) I had a record of 43 crashes in one week.

    Thanks everyone in this thread, I really appreciate the advice.



  • There will be a lot of times where you are asked to provide a type or package name as a string. Probably a good idea to use Type.class, or instance.getClass() and call getName on the result rather than fucking around with literal strings. Also helps ensure that you actually have that class on your classpath.


  • Discourse touched me in a no-no place

    I never really cared for the Spring MVC system; it was always just a bit too simple-minded for my applications.

    The GUIs for Maven are pretty good for simple applications, but it's once you're doing something really complicated that Maven starts to get good (or rather the opposition starts to get brain-hurtingly nasty). That's when you stop being able to use the GUIs so much, as they simply don't have the ability to cope with all the possibilities of all the Maven plugins (nor could they; there's a rich ecosystem of third party plugins there, some of which do really awesome build voodoo).



  • @scudsucker said:

    Postgress or MySQL

    Please note that MySQL has been renamed to MariaDB. If you want that engine, you should use the MariaDB branch, which has new, improved backends (MySQL is the Oracle branch where any actual improvements are closed-sourced and paid).

    Then, general wisdom these days tends to be that Postgress is generally preferred (Postgress is more featureful and has fewer quirks and is no longer as slow as it used to be, but is probably still a bit slower), but I don't have enough experience with either to provide any firm guidance (do have a look at how replication works in each in advance if there is a chance you'll need it and there probably is if you were planning Mongo).



  • @scudsucker said:

    Postgress or MySQL

    @scudsucker said:

    Further research

    While I have never set up either, I remember that setting up distributed/replicated database is rather complicated and comes with various limitations and trade-offs in both PostgreSQL and MariaDB/MySQL. Since you mention argument against Mongo that specifically concerns replication I suppose you are likely to need it, in which case you should really look at what options each provides and consider them before committing yourself to either.


  • Discourse touched me in a no-no place

    @Bulb said:

    Please note that MySQL has been renamed to MariaDB.

    FTFY… (and fuck Oracle).



  • @sloosecannon said:

    IntelliJ is honestly the best IDE I've used in my time developing. I can't really speak to the other IDEs but I've been thoroughly impressed by IntelliJ.

    It's the best IDE, but you've never used any other IDEs. Makes sense.

    Are you also that guy who keeps telling me how great Git is, then says he's never used any other source control software?



  • @Bulb said:

    Please note that MySQL has been renamed to MariaDB.

    That is a lie.

    MySQL is still MySQL.

    MariaDB is another brand-new database forked off of MySQL after Oracle bought them.

    @Bulb said:

    (MySQL is the Oracle branch where any actual improvements are closed-sourced and paid).

    OH LOOK! You KNEW it was a lie and typed it here anyway. You gigantic wanker.


  • :belt_onion:

    I have used other IDEs, and no, I'm not that guy.

    I wouldn't say a statement like that if I had only used one.



  • I tried all the Java IDEs for a while before settling on Netbeans. It's still a long way behind VS, but then Java is a long way behind .NET, so it all works out.



  • @sloosecannon said:

    I have used other IDEs,

    You know if you'd just have typed that the first time, instead of explicitly saying the opposite of it, you might have had a better time.

    Pro-tip for you.


  • :belt_onion:

    I... how did I say the opposite?

    I said it's the best IDE I've used - implying that I actually have used other ones.


Log in to reply