90

For c# developers that are staring out to learn Java, are there any big underlying differences between the two languages that should be pointed out?

Maybe some people may assume things to be the same, but there are some import aspects that shouldn't be overlooked? (or you can really screw up!)

Maybe in terms of OOP constructs, the way GC works, references, deployment related, etc.

mrblah
  • 99,669
  • 140
  • 310
  • 420
  • I think at least one of these might be a duplicate: http://stackoverflow.com/questions/614310/good-java-resources-for-c-developers http://stackoverflow.com/questions/870342/java-for-a-c-developer-closed http://stackoverflow.com/questions/90578/best-way-to-really-grok-java-for-a-c-guy http://stackoverflow.com/questions/72719/good-book-for-a-c-developer-going-over-to-java http://stackoverflow.com/questions/614310/good-java-resources-for-c-developers http://stackoverflow.com/questions/323015/best-way-to-learn-java-closed – Michael Myers Jan 06 '10 at 20:08
  • Also http://stackoverflow.com/questions/295224/what-are-major-differences-between-c-and-java. – Michael Myers Jan 06 '10 at 20:26
  • Also likely to be overlooked are our own "Hidden Features of C#" http://stackoverflow.com/questions/9033/hidden-features-of-c – John K Jan 13 '10 at 01:49

16 Answers16

135

A few gotchas off the top of my head:

  • Java doesn't have custom value types (structs) so don't bother looking for them
  • Java enums are very different to the "named numbers" approach of C#; they're more OO. They can be used to great effect, if you're careful.
  • byte is signed in Java (unfortunately)
  • In C#, instance variable initializers run before the base class constructor does; in Java they run after it does (i.e. just before the constructor body in "this" class)
  • In C# methods are sealed by default. In Java they're virtual by default.
  • The default access modifier in C# is always "the most restrictive access available in the current context"; in Java it's "package" access. (It's worth reading up on the particular access modifiers in Java.)
  • Nested types in Java and C# work somewhat differently; in particular they have different access restrictions, and unless you declare the nested type to be static it will have an implicit reference to an instance of the containing class.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 6
    +1 This is a great list for starters. – Joseph Yaduvanshi Jan 06 '10 at 17:24
  • 3
    @Jon Skeet: +1, And you would probably miss Lambda and LINQ until Java 7? – Kb. Jan 06 '10 at 17:57
  • @Kb: Yup, I miss it regularly :( – Jon Skeet Jan 06 '10 at 18:51
  • Not only bytes but all integer types are signed – Dave O. Jan 06 '10 at 19:54
  • 1
    "In C#, instance variable initializers run before the base class constructor does; in Java they run after it does (i.e. just before the constructor body in "this" class)" -- Eeer, could you elaborate this? Not sure I really understand what you're saying :) – cwap Jan 06 '10 at 19:55
  • 9
    @cwap: In C#, the execution order is "instance variable initializers, base class constructor, constructor body". In Java it's "superclass constructor, instance variable initializers, constructor body". (Instance variable initializers are what you get when you assign a value to an instance variable at the point of declaration.) – Jon Skeet Jan 06 '10 at 20:01
  • When you're talking about "instance variable initializers", you mean class A { int myInt = 4 /* <-- Here? */ } ? For a moment I thought you meant the classA A = new A(){myInt = 2}; which I didnt really believe :) – cwap Jan 06 '10 at 23:15
  • 1
    @cwap: Yes, that's what I mean - the latter is an *object* initializer. – Jon Skeet Jan 07 '10 at 07:19
  • I've never had to use an Enum, maybe I'm not doing it right... – Dhaivat Pandya May 24 '11 at 22:05
  • 1
    why no one speak about the absence of passing the parameter by reference in java so if you want to return multiple values you should create a type for that. also java have a labeled break and labeled continue which not found in C#. Java didn't have properties you should get and set attributes – Marzouk Jun 20 '15 at 15:43
22

here is a very comprehensive comparison of the 2 languages:

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

Added: http://en.wikipedia.org/wiki/Comparison_of_Java_and_C_Sharp

jspcal
  • 50,847
  • 7
  • 72
  • 76
20

I am surprised that no one has mentioned properties, something quite fundamental in C# but absent in Java. C# 3 and above has automatically implemented properties as well. In Java you have to use GetX/SetX type methods.

Another obvious difference is LINQ and lambda expressions in C# 3 absent in Java.

There are a few other simple but useful things missing from Java like verbatim strings (@""), operator overloading, iterators using yield and pre processor are missing in Java as well.

One of my personal favourites in C# is that namespace names don't have to follow the physical directory structure. I really like this flexibility.

ErikE
  • 48,881
  • 23
  • 151
  • 196
softveda
  • 10,858
  • 6
  • 42
  • 50
11

There are a lot of differences, but these come to mind for me:

  • Lack of operator overloading in Java. Watch your instance.Equals(instance2) versus instance == instance2 (especially w/strings).
  • Get used to interfaces NOT being prefixed with an I. Often you see namespaces or classes suffixed with Impl instead.
  • Double checked locking doesn't work because of the Java memory model.
  • You can import static methods without prefixing them with the class name, which is very useful in certain cases (DSLs).
  • Switch statements in Java don't require a default, and you can't use strings as case labels (IIRC).
  • Java generics will anger you. Java generics don't exist at runtime (at least in 1.5), they're a compiler trick, which causes problems if you want to do reflection on the generic types.
ErikE
  • 48,881
  • 23
  • 151
  • 196
Sneal
  • 2,546
  • 20
  • 22
  • 4
    Last I checked, strings did NOT overload ==, and I haven't heard of it being added for Java 7 either. They do, however, overload + for string concatenation. – Michael Madsen Jan 06 '10 at 19:46
  • 3
    Yes, comparing strings with == is a very common pitfall for newbies. `.equals` is what you have to use. – Michael Myers Jan 06 '10 at 20:09
  • Also, I don't understand the comment about static methods. Don't pretty much all languages allow static methods or the equivalent? – Michael Myers Jan 06 '10 at 20:12
  • I nearly upvoted this, but I disagree about generics. I like the type erasure. – finnw Jan 29 '10 at 01:46
  • 2
    "Switch statements in Java don't require a default" - nor does C#. – RenniePet Jul 12 '13 at 02:57
  • @finnw, you *like* type erasure!?!? Are you high? Even the designers of Java understood that it's a sacrifice for forwards-compatibility of the language for old JVMs. – Kirk Woll Dec 05 '13 at 02:39
  • Double-checked locking does work since Java 5 (if implemented correctly). – shmosel Jun 15 '17 at 19:49
9

.NET has reified generics; Java has erased generics.

The difference is this: if you have an ArrayList<String> object, in .NET, you can tell (at runtime) that the object has type ArrayList<String>, whereas in Java, at runtime, the object is of type ArrayList; the String part is lost. If you put in non-String objects into the ArrayList, the system can't enforce that, and you'll only know about it after you try to extract the item out, and the cast fails.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • 1
    ...although it's worth adding that you cannot put non-`String` objects in that list without making an unchecked cast, *somewhere*, and the compiler will correctly warn you at that point that the compiler can no longer check the generic bounds. So long as your list is *always* stored in a variable of `List`, attempts to insert a non-String object into it will not compile. – Andrzej Doyle Jan 06 '10 at 18:13
  • "non-String objects into the ArrayList, the system can't enforce that": Note that the system *does* enforce it at compile-time. You can however circumvent this by casting (or not using generics); then the runtime check will catch it, but only when extracting. – sleske Jan 06 '10 at 18:15
  • 1
    @Andrzej, @sleske: I'm only talking about runtime. Say you get the object via reflection, and invoke its `add` method (again, via reflection). Will the system reject a non-`String` object straight away, or only when casting the result of `get`? – C. K. Young Jan 06 '10 at 18:24
  • @sleske: But IIRC you only need an implicit cast to circumvent the type check. – Niki Jan 06 '10 at 20:17
  • @Judah: I rolled back your change (yes, a year after the fact), because you cannot have objects of type `List`. You can have objects of types descending from `List`, like `ArrayList` and `LinkedList`. (It's important to use `List` instead of `ArrayList` when passing them around, but it doesn't change the fact that you cannot say `new List()`.) – C. K. Young Jan 11 '11 at 16:55
  • Chris, in .NET you can do new List(). – Judah Gabriel Himango Jan 17 '11 at 04:32
  • Also, in .NET, there is no ArrayList. That's why I edited your answer in the first place. – Judah Gabriel Himango Jan 17 '11 at 04:33
  • @Judah: Okay, fair point. I'm a Java developer, so I answered for Java, not .NET. In Java, `List` is an interface, so you cannot have instances of it. – C. K. Young Jan 17 '11 at 04:47
  • Fair enough, we'll leave yours in place. – Judah Gabriel Himango Jan 23 '11 at 19:04
7

One thing I miss in C# from Java is the forced handling of checked exceptions. In C# is it far to common that one is unaware of the exceptions a method may throw and you're at the mercy of the documentation or testing to discover them. Not so in Java with checked exceptions.

Sean
  • 314
  • 1
  • 3
  • 2
    FWIW, this was considered in the dev't of C# and the rationale for leaving them out is real. Consider http://www.artima.com/intv/handcuffs.html . It's not that the designers are philosophically opposed to checked exceptions-- rather, they're waiting for a better technique that offers similar benefits without all the hairy drawbacks. – Greg D Jan 06 '10 at 17:47
  • Yes, yes, a very contentious subject... – sleske Jan 06 '10 at 18:18
  • 3
    I like the fact that C# does not have checked exceptions, but this was the first post to even point out the difference, so +1. – Nick Jan 06 '10 at 19:22
5

Java has autoboxing for primitives rather than value types, so although System.Int32[] is an array of values in C#, Integer[] is an array of references to Integer objects, and as such not suitable for higher performance calculations.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
4

No delegates or events - you have to use interfaces. Fortunately, you can create classes and interface implementations inline, so this isn't such a big deal

thecoop
  • 45,220
  • 19
  • 132
  • 189
  • 3
    "isn't such a big deal". Right. Because `x => x.Foo` vs. `new Bar() { public void M(SomeType x) { return x.Foo; } }` -- who cares about code being 10 times shorter? – Kirk Woll Dec 05 '13 at 02:43
2

The built-in date/calendar functionality in Java is horrible compared to System.DateTime. There is a lot of info about this here: What's wrong with Java Date & Time API?

Some of these can be gotchas for a C# developer:

  • The Java Date class is mutable which can make returning and passing dates around dangerous.
  • Most of the java.util.Date constructors are deprecated. Simply instantiating a date is pretty verbose.
  • I have never gotten the java.util.Date class to interoperate well with web services. In most cases the dates on either side were wildly transformed into some other date & time.

Additionally, Java doesn't have all the same features that the GAC and strongly-named assemblies bring. Jar Hell is the term for what can go wrong when linking/referencing external libraries.

As far as packaging/deployment is concerned:

  • it can be difficult to package up web applications in an EAR/WAR format that actually install and run in several different application servers (Glassfish, Websphere, etc).
  • deploying your Java app as a Windows service takes a lot more effort than in C#. Most of the recommendations I got for this involved a non-free 3rd party library
  • application configuration isn't nearly as easy as including an app.config file in your project. There is a java.util.Properties class, but it isn't as robust and finding the right spot to drop your .properties file can be confusing
Community
  • 1
  • 1
intoOrbit
  • 2,122
  • 2
  • 19
  • 21
1

There are no delegates in Java. Therefore, aside from all the benefits that delegates bring to the table, events work differently too. Instead of just hooking up a method, you need to implement an interface and attach that instead.

BFree
  • 102,548
  • 21
  • 159
  • 201
1

One thing that jumps out b/c it's on my interview list is that there is no "new" keyword analogue in Java for method hiding and there fore no compiler warning "you should put new here". Accidental method hiding when you meant to override leads to bugs.

(edit for example) Example, B derives from A (using C# syntax, Java behaves same way last I checked but does not emit compiler warning). Does A's foo get called, or B's foo? (A's gets called, probably surprising the dev who implemented B).

class A 
{
public void foo() {code}
}

class B:A
{
public void foo() {code}
}    

void SomeMethod()
{
A a = new B(); // variable's type is declared as A, but assigned to an object of B.
a.foo();
}
Jim L
  • 2,297
  • 17
  • 20
  • 2
    How do you accidentally hide an instance method in Java? they're either final - so no override or `new` method to intentionally hide - or non-final so overridden rather than hidden. – Pete Kirkham Jan 06 '10 at 18:46
  • Added example. I haven't tested it in Java in a while, but the interview question originally came from the Java group from my previous company. In C#, the compiler warning usually means that people change the name. I admit it is pretty odd case, but OP seemed to be asking for things that would be potential hard to find problems when switching langs. – Jim L Jan 06 '10 at 20:35
  • 1
    The difference here is that in Java all methods are virtual (so in Java, it will be B.foo() that gets called because Java always does dynamic method dispatch), whereas in C# methods are not virtual by default (and A.foo() would be called). Many coding style checkers for Java will tell you that B should use the @Override annotation. – William Billingsley Jan 07 '10 at 03:32
1

The most harrasing difference to me when I switch to java it's the string declaration.

in C# string (most of the time) in Java String

It's pretty simple, but trust me, it makes you lose so much time when you have the habit to s not S !

FMFF
  • 1,652
  • 4
  • 32
  • 62
iChaib
  • 469
  • 4
  • 10
  • 17
1

Java doesn't have LINQ and the documentation is hell. User interfaces in Java are a pain to develop, you lose all the good things Microsoft gave us (WPF, WCF, etc...) but get hard - to - use, hardly documented "APIs".

Turing Complete
  • 929
  • 2
  • 12
  • 19
0

The one issue I've run into so far when working with Java coming from C# is Exceptions and Errors are different.

For example you cannot catch an out of memory error using catch(Exception e).

See the following for more details:

why-is-java-lang-outofmemoryerror-java-heap-space-not-caught

Community
  • 1
  • 1
Crispy
  • 5,557
  • 3
  • 30
  • 35
  • It's intentionally designed that way to discourage the application programmer from catching it – finnw Jan 29 '10 at 01:49
  • Yeah I'm sure it was, but coming from the C# side, where all you have to worry about is catching exceptions, threw me for a loop :) – Crispy Jan 29 '10 at 04:29
0

It's been so long since I've been in Java but the things I noticed right off the bat in application development was C# event model, C# drag and drop vs using Layout Managers in Swing (if your doing App dev), and exception handling with Java making sure you catch an exception and C# not required.

0

In response to your very direct question in your title:

"C# developers learning Java, what are the biggest differences one may overlook?"

A: The fact that Java is considerably slower on Windows.

  • 4
    I run OpenSuSE 64bit and Windows 7 64bit, and Eclipse IDE is ("seems") faster in Windows. Is your answer based on personal observation or on actual benchmarks? – Joseph Yaduvanshi Aug 18 '10 at 13:34