What are major differences between C# and Java?
Asked Answered
I

7

209

I just want to clarify one thing. This is not a question on which one is better, that part I leave to someone else to discuss. I don't care about it. I've been asked this question on my job interview and I thought it might be useful to learn a bit more.

These are the ones I could come up with:

  • Java is "platform independent". Well nowadays you could say there is the Mono project so C# could be considered too but I believe it is a bit exaggerating. Why? Well, when a new release of Java is done it is simultaneously available on all platforms it supports, on the other hand how many features of C# 3.0 are still missing in the Mono implementation? Or is it really CLR vs. JRE that we should compare here?
  • Java doesn't support events and delegates. As far as I know.
  • In Java all methods are virtual
  • Development tools: I believe there isn't such a tool yet as Visual Studio. Especially if you've worked with team editions you'll know what I mean.

Please add others you think are relevant.

Update: Just popped up my mind, Java doesn't have something like custom attributes on classes, methods etc. Or does it?

Imperium answered 17/11, 2008 at 10:7 Comment(4)
Languages are different from language implementations, which are also different from libraries. What are you trying to compare?Candlemaker
See Comparison of C Sharp and Java.Reisman
I found this one msdn.microsoft.com/en-us/library/ms836794.aspx It covers both the similarity and difference between C# and java.Quinones
You can get many of the things mentioned below about Java with the right libraries. Check for example this valid Java code: new String[] { "james", "john", "john", "eddie" }.where(startsWith("j")).distinct(); It uses a library called lombok-pg. Can be found at github.com/nicholas22/jpropelTitian
S
328

Comparing Java 7 and C# 3

(Some features of Java 7 aren't mentioned here, but the using statement advantage of all versions of C# over Java 1-6 has been removed.)

Not all of your summary is correct:

  • In Java methods are virtual by default but you can make them final. (In C# they're sealed by default, but you can make them virtual.)
  • There are plenty of IDEs for Java, both free (e.g. Eclipse, Netbeans) and commercial (e.g. IntelliJ IDEA)

Beyond that (and what's in your summary already):

  • Generics are completely different between the two; Java generics are just a compile-time "trick" (but a useful one at that). In C# and .NET generics are maintained at execution time too, and work for value types as well as reference types, keeping the appropriate efficiency (e.g. a List<byte> as a byte[] backing it, rather than an array of boxed bytes.)
  • C# doesn't have checked exceptions
  • Java doesn't allow the creation of user-defined value types
  • Java doesn't have operator and conversion overloading
  • Java doesn't have iterator blocks for simple implemetation of iterators
  • Java doesn't have anything like LINQ
  • Partly due to not having delegates, Java doesn't have anything quite like anonymous methods and lambda expressions. Anonymous inner classes usually fill these roles, but clunkily.
  • Java doesn't have expression trees
  • C# doesn't have anonymous inner classes
  • C# doesn't have Java's inner classes at all, in fact - all nested classes in C# are like Java's static nested classes
  • Java doesn't have static classes (which don't have any instance constructors, and can't be used for variables, parameters etc)
  • Java doesn't have any equivalent to the C# 3.0 anonymous types
  • Java doesn't have implicitly typed local variables
  • Java doesn't have extension methods
  • Java doesn't have object and collection initializer expressions
  • The access modifiers are somewhat different - in Java there's (currently) no direct equivalent of an assembly, so no idea of "internal" visibility; in C# there's no equivalent to the "default" visibility in Java which takes account of namespace (and inheritance)
  • The order of initialization in Java and C# is subtly different (C# executes variable initializers before the chained call to the base type's constructor)
  • Java doesn't have properties as part of the language; they're a convention of get/set/is methods
  • Java doesn't have the equivalent of "unsafe" code
  • Interop is easier in C# (and .NET in general) than Java's JNI
  • Java and C# have somewhat different ideas of enums. Java's are much more object-oriented.
  • Java has no preprocessor directives (#define, #if etc in C#).
  • Java has no equivalent of C#'s ref and out for passing parameters by reference
  • Java has no equivalent of partial types
  • C# interfaces cannot declare fields
  • Java has no unsigned integer types
  • Java has no language support for a decimal type. (java.math.BigDecimal provides something like System.Decimal - with differences - but there's no language support)
  • Java has no equivalent of nullable value types
  • Boxing in Java uses predefined (but "normal") reference types with particular operations on them. Boxing in C# and .NET is a more transparent affair, with a reference type being created for boxing by the CLR for any value type.

This is not exhaustive, but it covers everything I can think of off-hand.

Snotty answered 17/11, 2008 at 10:16 Comment(58)
I'm not sure on how static classes work in C#, but Java has enum classes which ought to be similar.Alsatian
@JesperE: No, enum classes aren't really like static classes in C#. You can still pass enums as parameters, use them as variables, define instance mtehods etc in Java. In C# static classes are just used for utility methods, basically. (There can be static state in the class, but no instance state)Snotty
"Java doesn't have static classes (which don't have any constructors..." Apart from static constructors! :)Measures
When you see it spelled out like that, I suddenly get a better understanding of why I have had this feeling that Java is inferior to C#.Fractionate
"Java doesn't have static classes (which don't have any instance constructors, and can't be used for variables, parameters etc)" -- I've never really been sure what the point of static classes are... I can have a class containing only static methods in Java.Crutch
@R Bemrose: In Java, if you want to make a class uninstantiable, you have to explicitly declare a private constructor. That doesn't stop you from creating an instance within the class. It also doesn't stop people from trying to use the type for variables etc. Static classes signal intent.Snotty
"Java doesn't have anonymous types". Not true. In order to have anonymous inner classes, anonymous types are a must. With that said, to make anonymous types really useful, you need type inference. C# has this, Java does not.Tejada
True, there are anonymous types. I will clarify it to "Java has no equivalent of C# anonymous types."Snotty
"Java doesn't have the equivalent of "unsafe" code"... Java does support the native keyword which is less functional, but does still allow the programmer to step outside of the managed runtime.Folacin
@Michael: It's not the same thing at all IMO. That would be akin to P/Invoke, not unsafe C# code.Snotty
@Morten Christiansen: Yeah, it seems like that. But simplicity (in terms of simple definition - simple usage is another story) is also a strength, so Java might be superior ;)Celibacy
@Brian: I think Java generics and the details of inner classes pretty quickly quash the idea of Java achieving superiority through simplicity ;)Snotty
Wow. A lot of good info here. Like any large subject, of course one must omit more than one covers. But these individual points are all worth reading. Great answer.Gonyea
@jpartogi: Well, Java 7 should help on at least some of these points. And there's more to life than being the new and shiny thing on the block. Having said that, I still definitely prefer C# to Java :)Snotty
Thanks Jon. I will consider learning C# now. It looks very good. Only God knows when Java 7 will be out. =DFactory
@CrazyJugglerDrummer - Some would argue that makes Java better. Being able to do more things increases the likelyhood that you'll do them wrong.Subinfeudate
@OrangeDog: People arguing that are mostly kidding themselves, IMO. It's hard to see how being forced to write an explicit try/finally block is less error-prone than a using statement, IMO. Most of C#'s "extra" features compared with Java mean that you can get away with writing less code, and that that code can be more readable.Snotty
@Jon Skeet - No offence, but you're not exactly impartial. In my experience people with a year's Java experience write better code than people with a year's C# experience.Subinfeudate
@OrangeDog: How impartial are you, out of interest? Yes, I'm a C# enthusiast, but with pretty significant Java experience too - it's my day job, after all. It's not like I'm ignorant of how to use Java effectively.Snotty
@Jon Skeet - Well I have no affiliation with Sun, Oracle or any Java language designers. I like C# for its lambdas, unfortunately due to the complexity of other language features you can't formulate any proofs about them. Java's simpler and more consistent semantics lead to more powerful proofs that programs are correct.Subinfeudate
@OrangeDog: And yet I see plenty of bugs in Java code. How many people are using these proofing tools? Realistically I believe it's a tiny, tiny proportion of users. Note that most of the language features only do things you could write more longwindedly in C# without using lambda expressions. So you could consider a proofing tool for the more complex form by performing a translation into the simpler form and running the proof on that. (In terms of impartiality, bear in mind that I don't work for Microsoft... Yes, I know some of the C# team, but I'm unrestrained in C# criticism too.)Snotty
@Jon Skeet - I wasn't suggesting that simply being able to formulate proofs on the language would automatically remove bugs. I was using it as empirical evidence that Java is easier to reason about correctly. I don't think there is an automated Java prover yet - I do my sequent calculus by hand :)Subinfeudate
@Jon Skeet - Neither does not using lambdas solve the provability problem for C#. At minimum you would also have remove unsafe from the language entirely. Any syntax construction whose behaviour is undefined is really going to throw a spanner in the works. I would guess you also have to remove most of what C# has that Java doesn't.Subinfeudate
@OrangeDog: For a start, most developers don't write code using "unsafe" as far as I'm aware, so that's a red herring. I also think that provability is a red herring - I don't think formal provability has very much to do with how easy it is for a human to reason about code. My point is that as someone who is pretty experienced in both Java and C#, I find C# to be a far superior language in terms of productivity and readability. If you feel the opposite, could you clarify your levels of experience in both languages? I think it's pretty relevant to the discussion.Snotty
@Jon Skeet - It's not about whether it's used, but mere fact that it exists in the language. Aside from that, there's no way to know for sure whether features are being used in your application, unless you wrote all your code on your own and read all the source code for any and all libraries you use. I do not hold an opinion on productivity and readability. All I suggested was that more features provide more opportunity to make mistakes.Subinfeudate
@OrangeDog: Well, it's partly about whether or not it's used. There are plenty of obscure areas of Java, particularly around generics. And actually it's really easy to tell whether or not a particular C# project uses unsafe anywhere: you look in the project settings. By default, you can't use unsafe code... you have to tell the compiler to let you do it. And you didn't just suggest that more features provide more opportunities to make mistakes - you said: "Some would argue that makes Java better" with the implication (IMO) that you are one of those people.Snotty
@OrangeDog: Furthermore, your claim that "Being able to do more things increases the likelyhood that you'll do them wrong" is also a fallacy IMO... because it assumes that if you can't do something using a feature of the language which makes it easy, you won't have to do it at all. That's simply untrue - often the tasks you need to accomplish in Java and C# are the same, but due to missing features, Java makes it harder to accomplish those tasks correctly. By simplifying the task, the feature decreases the likelihood that you'll do it wrong.Snotty
@Jon Skeet - Actually I was pointing out to CrazyJugglerDrummer that he was making the equally flawed assumption that more features = better.Subinfeudate
@OrangeDog: If you'd only said that, it would have been fine. But no, you started on provability and all kinds of other things. You still haven't answered my question about how much C# experience you have, by the way.Snotty
@Jon Skeet - I did only say that, but was immediately challenged to back it up by you. I have probably spent about a man-year working in C#. As I said, I quite like some of the features, but someone who doesn't know what they're doing (or is having an off day) can really screw you over with hidden bugs, to an extent simply not possible in Java. Also, you neglected to consider linking to DLLs that were compiled with unsafe enabled.Subinfeudate
@OrangeDog: No, you didn't only say that the "more features = better" assumption is wrong: you claimed that "Being able to do more things increases the likelyhood that you'll do them wrong." That's not the same thing. You then questioned my impartiality, brought up provability and various other aspects which I frankly view as FUD. If you're going to include linking to DLLs using unsafe code, you'd better also include calling Java which uses JNI. You've neglected the kinds of bug which are possible in Java but not C# - for example calling a static method via a reference (continued)Snotty
@OrangeDog: ... such as creating a new thread and calling thread.Sleep(1000) - which makes it look like you're telling the new thread to sleep, but actually it's the current thread which will sleep. You can't do that in C#. Someone who doesn't know what they're doing will screw up in either language. There are gotchas for both languages, obviously - but my experience (which sounds like it's rather more balanced than yours, with several years in both languages) - is that the gotchas in C# are almost all easily found and fixed, and easily made up for by the benefits in productivity.Snotty
@Jon Skeet - 1) You list yourself as author of a major C# book and as Microsoft MVP. One assumes therefore that you're biased towards C#. 2) What you view as FUD I view as crucial to evaluation of a language - the implications of its semantics. 3) Static method via reference generates a compile warning, so that's not a major issue. 4) Dynamic linking is rare in Java, but much more common in C#. 5) If you want obfuscation opportunities, operator overloading is the biggie. With Java you always know what . is going to do, without having to check library documentation.Subinfeudate
@OrangeDog: 1) I also list myself as an engineer at Google. As I've said already, I primarily use Java in my day to day job. If I've tried both languages extensively and prefer C#, does that make me biased necessarily? Or is it maybe just an outcome of the differences between the languages? 2) Provability is crucial to the evaluation of a language for you? Wow. 3) Calling a static method via a reference generates a warning in some IDEs, but not in javac (even with -Xlint). Btw, I could probably find you the Eclipse feature request where I suggested making it a warning. (Continued)Snotty
4) By "dynamic linking" do you mean JNI vs P/Invoke? If so, it entirely depends on what you're doing. I hardly ever use it in C#. 5) Operator overloading doesn't do a lot for "." (although extension methods do). When it comes to gotchas and operator overloading though, have you noticed how one of the biggest gotchas in Java is people comparing strings with ==? It turns out it's kinda nice to have that available... although obviously you do need to know what's going on in order to use the language effectively. I treat that as a given for any language.Snotty
@Jon Skeet - 2) Without a context of what the target problem is, yes - semantic implications are the most important. 4) No, JNI vs. DLLs, as we were discussing. 5) I disagree. I know that in Java == will always be object identity while equals() will be logical equality. In C# however, that default behaviour of == can be overridden to do anything at all. In a huge project that's can be hard to spot.Subinfeudate
@OrangeDog: 2) I suggest that you're in a tiny minority in terms of performing provability analysis by hand. And as I've pointed out, most of the C# features can be treated provably anyway. 4) In that case I don't see your point, as most significant Java projects are going to use jar files... don't confuse "native DLL" with "class library DLL" in .NET. Which are you talking about? 5) The behaviour can't be overridden; it can be overloaded. I rarely see people getting confused by this in C# (although of course it happens) but there are loads of Java string comparison questions on it.Snotty
@OrangeDog: (Continued) Again, anyone who knows both languages well is unlikely to have a problem with it. I note you still haven't responded to my main point that if you're trying to accomplish the same task in both languages, the extra features of C# often help you to do that in less code, reducing the likelihood of making mistakes rather than increasing it. This is a refutation of your original point that "Being able to do more things increases the likelyhood that you'll do them wrong." Are you still trying to maintain that claim?Snotty
@Jon Skeet - 2) Yes, I am. Most people have little grasp of semantic reasoning techniques. If I have time I could find a paper demonstrating that C# features cannot be "treated provable", but you'll probably have to at least start a PhD on the subject to understand it. 4) You're point was that the existence of DLLs is irrelevant as Java has JNI. My point was that DLLs are used orders of magnitude more often than JNI. 5) Changing the behaviour of a == b is a semantic override, not overload. Different syntax is required to access the original behaviour.Subinfeudate
4) No, my point was that "you can unwittingly link to a DLL which uses unsafe code" is invalidated by "you can unwittingly link to a jar file which uses JNI". 5) In language terms (which I believe should be used as we're talking about the languages) the operator is overloaded, not overridden. The behaviour differs depending on the operand types. I suspect we're beyond the point at which this discussion is really useful though... I stand by my belief that the new features of C# make it easier to write correct code. If you disagree, so be it. I doubt that either of us will persuade the other.Snotty
@Jon Skeet - The context I am thinking of is a large project spanning 6+ months with 10+ developers of various proficiencies. In such a situation you cannot make assumptions of what features people will and won't use, or even know about. In my experience the number of language-related bugs increases with the complexity of the language. C < Java < C#. However, C of course by far excels in memory-related issues, and C# usually results in faster writing of code (modulo number of IDE power-users).Subinfeudate
@OrangeDog: I would expect code review (when properly set up) to help that significantly and improve the level of knowledge of the coders. I'd also expect there to be many other kinds of mistake which are avoided due to the language features.Snotty
@Jon Skeet - Indeed, but I find code review to only remove a proportion of total bugs, and to be less effective on bugs concealed by language abstractions.Subinfeudate
@OrangeDog: Whereas I find it's a really good way of more experienced devs tutoring less experienced ones on good use of the language. Experience varies... but I would still expect to see fewer bugs overall from a C# codebase, simply because things like using statements are simpler to get right than try/finally blocks, etc. Oh, and Java generics give a whole extra can of worms to consider...Snotty
@Jon Skeet - I think we should stop now, as the merits of code review it's quite distant from whether more features do or do not make a language "better", which is itself distant from the actual question at the top of the page.Subinfeudate
@OpenMind: in SE 7 you can finally switch on strings #338706 :D but I really wish they would implement automatic properties and implicitly typed local variables, all that redundancy hurts my eyes (and thingers) xDPalmerpalmerston
@MichaelArdan One easily makes an argument with Skeet, but one is incapable of winning it without providing unbiased, tested theories with physical implementations backed up with either experience or a whole range of sources from reputable developers of both sides of the argument :)Footlocker
Nice answer, but it is a long time since it was written. Could you revise it, please?Shoa
@OndrejJanacek: Any specific bits you think should change? When Java 8 is released there'll be a fair amount, but I'm not sure what you'd want changed before then.Snotty
@JonSkeet I see it. I used a wrong question. I didn't really mean "Could you revise it", but I ment "Is it up to date?". Sorry for my bad english skills regarding asking correct questions. Also, I don't know much about Java and I thought that something must have changed since you wrote this text.Shoa
@OndrejJanacek: It's already been revised for Java 7 with the try-with-resources being equivalent to C#'s using statement. There are a few other features in Java 7 which don't have an equivalent in C#, but nothing sufficiently important to merit including in this list, IMO.Snotty
@EduardDumitru: Have you considered adding an answer yourself? Stack Overflow comments aren't really designed for this sort of thing.Snotty
Maybe this question/answer is up for an update to Java 8 and C# counterpart (can't image them changing nothing since 2008)? Not sure if that's the right thing to do with 5 year old questions.Faltboat
@skiwi: It's hard to say, to be honest. It will get really unwieldy with Java 8 and C# 6, neither of which is "out" yet - I think it might be best to leave it at a snapshot in time.Snotty
I wondered. you edited the question to java 7. wouldn't it be advantegous to write the answer with something similar to this in mind: "this answer defaults to java 7 ... -point 1 -point 2 -point 3 -Java 1-6: Java 6 doesn't have an equivalent of the using statement for simplified try/finally handling of resources -point 5 -etc". keeping the differences in a single list. denoting if a line only applies to language version n to mPhosphoric
@naxa: I think it would get pretty long-winded to maintain that - especially as C# moves along as well. Basically you'd need to end up with a full matrix, updated with each release. I don't think I want to go there...Snotty
@JonSkeet well is it? isn't the current version potent to slowly becoming out of date? the alternative I've mentioned seems to me just a matter of adding prefixes to lines that got invalidated over time. and the lines for 'default versions' wouldn't be prefixed. maintained perhaps only at major version releases. whatever, just an idea.Phosphoric
@naxa: Put it this way - I don't have time to do it now, but if you'd like to have a go, feel free to propose it as an edit (and refer to this comment).Snotty
G
24

The following is a great in depth reference by Dare Obasanjo on the differences between C# and Java. I always find myself referring to this article when switching between the two.

http://www.25hoursaday.com/CsharpVsJava.html

Greenheart answered 17/11, 2008 at 10:55 Comment(3)
@Jon Skeet: you are the most C# active developer. Why don't you maintain your version of C# & Java differences. I bet people would love to read it.Revamp
@claws: I haven't got time to do everything I'd like to.Snotty
@Winston: We need a "differences between Chuck Norris and Jon Skeet" list: 1) Chuck Norris always has time; Jon must modify the TimeDate class in order to always have time, and has not had time to yet :(Bowes
F
11

C# has automatic properties which are incredibly convenient and they also help to keep your code cleaner, at least when you don't have custom logic in your getters and setters.

Fractionate answered 17/11, 2008 at 13:56 Comment(0)
R
10

Features of C# Absent in Java • C# includes more primitive types and the functionality to catch arithmetic exceptions.

• Includes a large number of notational conveniences over Java, many of which, such as operator overloading and user-defined casts, are already familiar to the large community of C++ programmers.

• Event handling is a "first class citizen"—it is part of the language itself.

• Allows the definition of "structs", which are similar to classes but may be allocated on the stack (unlike instances of classes in C# and Java).

• C# implements properties as part of the language syntax.

• C# allows switch statements to operate on strings.

• C# allows anonymous methods providing closure functionality.

• C# allows iterator that employs co-routines via a functional-style yield keyword.

• C# has support for output parameters, aiding in the return of multiple values, a feature shared by C++ and SQL.

• C# has the ability to alias namespaces.

• C# has "Explicit Member Implementation" which allows a class to specifically implement methods of an interface, separate from its own class methods. This allows it also to implement two different interfaces which happen to have a method of the same name. The methods of an interface do not need to be public; they can be made to be accessible only via that interface.

• C# provides integration with COM.

• Following the example of C and C++, C# allows call by reference for primitive and reference types.

Features of Java Absent in C#

• Java's strictfp keyword guarantees that the result of floating point operations remain the same across platforms.

• Java supports checked exceptions for better enforcement of error trapping and handling.

Relict answered 4/1, 2012 at 16:1 Comment(0)
D
9

Another good resource is http://www.javacamp.org/javavscsharp/ This site enumerates many examples that ilustrate almost all the differences between these two programming languages.

About the Attributes, Java has Annotations, that work almost the same way.

Dustindustman answered 20/11, 2008 at 13:40 Comment(0)
E
5

Generics:

With Java generics, you don't actually get any of the execution efficiency that you get with .NET because when you compile a generic class in Java, the compiler takes away the type parameter and substitutes Object everywhere. For instance if you have a Foo<T> class the java compiler generates Byte Code as if it was Foo<Object>. This means casting and also boxing/unboxing will have to be done in the "background".

I've been playing with Java/C# for a while now and, in my opinion, the major difference at the language level are, as you pointed, delegates.

Ene answered 17/11, 2008 at 10:14 Comment(7)
This is wrong, generics erasure or reification (Java and C# respectively) doesn't necessarily affect performance.Candlemaker
You're confusing autoboxing with casting.Alsatian
No, bruno is right about the performance difference. There's no way of getting the equivalent of a List<byte> (generically) in Java. You'd have to have a List<Byte> which would incur boxing penalties (time and memory).Snotty
The (un)boxing only happens for boxed types, which are primitive types.Candlemaker
Please see this article: jprl.com/Blog/archive/development/2007/Aug-31.htmlEne
Miguel: Sure, but at that point it certainly affects performance! (And there's also no need for the CLR to perform a casting type check when fetching from a generic list; it knows the type will be correct.)Snotty
So to sum it up, in C# generics improves performance, in Java its the opposite :)Gabie
G
0

Please go through the link given below msdn.microsoft.com/en-us/library/ms836794.aspx It covers both the similarity and difference between C# and java

Globin answered 2/5, 2014 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.