The Joel on Software Discussion Group (CLOSED)

A place to discuss Joel on Software. Now closed.

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

What is the difference between C# and Java

Hi

What will be your 'interview answer' to this question

Thanks.
FromEmeraldCity Send private email
Friday, February 23, 2007
 
 
It would vary entirely depending on whether I thought the person interviewing me was a MSFT-lover or a MSFT-hater.
Greg Send private email
Friday, February 23, 2007
 
 
Java is a big pile of steaming poo marketed by a restarded hardware company that know jackshit about software marketing, the "write once, run everywhere" became the joke of the industry and its CEO play pissing game with Uncle Billy. It was a great tool until it overarchitectured than it need to be and too complex to even bother with it.

Uncle Billy hired Uncle Hejlsberg to take the idea of Java and make something useful with the promise of write once and run it well on Windows.
.
Friday, February 23, 2007
 
 
Strange how people often equate Java with other technologies built using Java.
Anindya Mozumdar Send private email
Saturday, February 24, 2007
 
 
C# is a reengineered version of Java which fixes some of the more obvious deficiencies and uses a more Win32 model of GUI programming (yay! I like the Win32 model of GUI programming) instead of the weird Swingy way of doing it.

C# is also more focused on wizards *sigh* then factories *double... no, triple sigh*.

<controversial>
C# also has a decent IDE.

I haven't tried Eclipse though, maybe it's a bit better than IntelliJ (almost-but-not-quite-half-decent. The features are there - it's just lots of little annoyances that are the problem).
Jivlain
Saturday, February 24, 2007
 
 
yBva, in ASCII, taking the bytewise difference modulo 128.

Which is a programmer way of saying "please define your question properly".
Iago
Saturday, February 24, 2007
 
 
I hate Java for not having unsigned data types.
That alone is reason enough to not use it.
adsf Send private email
Saturday, February 24, 2007
 
 
"C#, as of 2.0, supports generics.  The way C# implements the accessor pattern (with get/set) is also a new idea in C# which improves over Java."

I'd start with that.
John Cromartie
Saturday, February 24, 2007
 
 
Ans: The most fundamental and defining difference is that C# is a 'pure' OO language while Java is not.
Java has primitive types which are not Objects; in C# everything is an Object.

This is the correct answer and you might fail this question if you don't mention it somewhere in you answer.
indian
Saturday, February 24, 2007
 
 
Also, I think it may be helpful to mention some other rather important difference like C# has support for both structures (value types) and classes (reference types) while Java just has classes (reference types) and primitives.
C# has support for function pointer like constructs (delegates; Java doesn't) and was first to support both attribute based (i.e. declarative programming) and generic programming.
indian
Saturday, February 24, 2007
 
 
They both suck and intentionally under-innovate in order to avoid scaring corporate America, who wants vast supplies of interchangeable programmers they can all treat like shit.

Thinking this is an unreasonable situation means you're a ridiculous Ivory Tower propellerhead.
Warren Send private email
Saturday, February 24, 2007
 
 
C# rules and Java drools? So when do I start?
dood mcdoogle
Saturday, February 24, 2007
 
 
> I hate Java for not having unsigned data types.

What difference does it make?
son of parnas
Saturday, February 24, 2007
 
 
It depends which end of the egg you open first.
old.fart
Saturday, February 24, 2007
 
 
Okay, this is kind of scatterbrained, but bear with me...

I've been using C# for about six months on some of my own personal projects, after using Java for about seven years. I continue to use Java at work, and for a few of my personal projects (if there's a Java library that I can't live without, and no .NET equivalent). All in all, I've grown very fond of C#.

Here are some of my observations:

C# has unsigned data types. Java doesn't. In addition, C# offers a 'decimal' primitive type, whereas in Java you'd need to use a BigDecimal object.

Primitive types in C# can be declared as 'nullable'. Java doesn't offer nullable primitives.

In addition to objects and primitives, C# also offers structs. Java doesn't. Structs in C# are more distinct from classes than C++ structs, since C# structs are allocated on the stack (rather than the heap), and they're passed by value (rather than by reference).

In Java, event-based programming is usually implemented using Observer and Listener patterns, with anonymous inner classes as the event handlers. C# actually has a primitive 'event' type which can be invoked from any method. The events are handled by delegates, which can be registered as event handlers for particular types of events.

C# provides the 'unsafe' keyword, so that you can temporarily bypass the type-system, manipulating pointers and performing potentially type-unsafe pointer casting operations. When manipulating pointers, you can mark a particular variable as 'fixed' so that the GC will refrain from moving the object while it's being manipulated. Pointer logic in C# is rarely necessary, but occasionally indispensable.

C# offers the notion of a 'partial class' definition. You can define some of your fields and methods in one source file, and implement the rest of it in another source file. This is handy for merging auto-generated class definitions with your own extension methods.

C# has true rectangular arrays. Java only offers multidimensional "jagged" arrays (arrays of array-pointers, really (which are, of course, also available in C#)).

Java generics are implemented using a compiler trick to check for type-safety. At runtime, all the type-information of generic types is lost, so the runtime still performs casts whenever pulling objects of a collection. Also, due to the limitations of compile-time checking in the Java generics model, it's still possible to perform unsafe casts at runtime. Also, it's impossible to use primitive types with the Java generics implementation. Objects only.

In C#, the generics implementation is built into the runtime, so the superfluous casts are eliminated. The compiler actually generates different bytecode for each parametric type (much like C++ templates), though all reference-type generics share code. In C#, it's perfectly legal to use primitive types in generic collections, without boxing/unboxing, so you get a bit of a performance boost there.

Even though C# has a better generics implementation, the collections library in Java is waaaaay better. The interface/implementation hierarchy in the Java collections API is only poorly mimicked in the C# implementation. Java also has a more diverse set of collection classes, and there are lots of little perks in the Java collections API that were missed in the C# implementation. For example, Java's Collection.binarySearch() method returns (-(insertionPoint) - 1) if the item doesn't exist in the collection, so it's easy to insert an item at the correct index of a sorted list, if it's not already there. In C#, the binary search function just returns -1 if the item isn't in the collection.

Lame.

In Java, the 'enum' type is implemented as an object with some built-in functionality. Enums can inherit from one another, they can have their own constructors and methods and private fields, and everything. And, by some bizarro mobius-strip universe-bending phenomenon, Java enums are actually defined as Enum<T extends Enum<T>>. (Cue the sound of my head exploding.) In C#, enums are much simpler. They're based on an underlying integer type, and each value has a string equivalent. Your enums can't have methods or constructors or private fields, but why would you need those things anyhow?

C# provides a handy syntax for defining properties (getters & setters). In Java, getters and setters are just ordinary methods.

C# has operator overloading (for all unary, binary, and relational operators). It also allows the array-indexing operator to be overloaded, so List and Dictionary (Map) classes can use collection[index] syntax, rather than collection.get(index) method calls. I didn't realize how much I prefer the C# syntax until I had to go back and write a bunch of code to manipulate Java collections, and I found the method-call syntax kind of annoying.

In C#, the 'switch' statement allows for cases with String values (or null). In Java, the switch statement only applies to cases with byte, short, char, and int primitive types. Also, the C# switch statement eliminates implicit case-fallthrough, which sometimes results in buggy code when people forget to add 'break' statements at the appropriate locations.

C# also has a 'goto' keyword. Holy crap. Don't use it!!!

C# allows multiple classes, structs, interfaces, etc to be defined in each source file. And C# source files aren't required to be in a directory hierarchy that mirrors the package structure. Java dictates one class per file, and the directory hierarchy must match the package hierarchy. As it turns out, I prefer the Java package hierarchy, so that's the way I always organize my C# projects.

There are no checked exceptions in C#, so you're never *required* to use a try/catch block.

Both languages support embedded documentation, but I think Javadoc produces better output files than the C# doc processor.

Java's inner classes are a little bit better than C# inner classes. In Java, any inner class definition retains an implicit reference to the object which contains it. In C#, you have to explicitly pass the inner object a reference to the outer object, or else it will be ignorant of its context.

Java class files are usually packaged up into JAR archives (which are just zip files with a different file extension, and potentially containing a MANIFEST file describing the contents of the archive). In C#, bytecode is packaged into 'assemblies' (which have a DLL file extension). When the Java classloader accesses classes from a JAR file, it promptly forgets where the classes came from, so it's very difficult at runtime to determine which classes were loaded from which JAR file. In C#, there's a boatload of functionality for loading an assembly into its own sandboxed 'AppDomain'. It's possible to restrict the privileges of the code running in any subordinate AppDomain. Java has a similar security model, but without first-class treatment of JAR archives in the runtime, it's awkward to set up those security structures.

In addition to public/private/protected access modifiers, C# has an 'internal' keyword, which makes a method or field accessible to any class in the same assembly. Although this makes it possible to increase coupling between classes, the coupling is invisible from the perspective of the library consumer. And sometimes it's just so damn handy to have methods that are publicly available within the assembly but private to any external consumers.

C# still has some relics of the old DLL hell from its COM heritage. This is because there are certain core assemblies loaded in the Global Assembly Cache. You can override the settings of the GAC, but it's a minor pain in the ass.

When you build a C# application, you get EXEs and DLLs. When you build a Java application, you get CLASS files and JARs. There are tools to embed a Java application into an EXE launcher, but an EXE should be the default launching mechanism, not a 3rd party add-on.

I haven't used the WPF gui stuff yet (rich client GUI with XML), but I'm excited about it. I'm not crazy about writing Swing GUI code, even though I think Swing on Windows looks pretty good these days (as of JDK6).

I like Eclipse better than Visual Studio.
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
Hmmmmmm... That's a bit long for an "interview answer".

If I was asked that question in an interview, I'd talk about the differences in the type system, the assembly vs JAR packaging mechanisms (and the resultant classloader issues), the differences in the generics implementations, and the collections APIs.

I'm sure there are also important distinctions in the threading libraries, but I'm not familiar enough with them to discuss the differences.

I'd probably also mention that the Java community tends to be much more framework-oriented, while the .NET community is more library/application oriented. And the Java community has produced far more open-source projects than the .NET community.

Also, I know nothing about ASP.NET, so I couldn't discuss how it differs from J2EE.
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
Wow! I was going to say they're pretty much two variations on the same theme, but Benji is a little more thorough than that!
Mike S Send private email
Saturday, February 24, 2007
 
 
> That's a bit long for an "interview answer".

I'd say the biggest difference is Java runs everywhere and C# will only run on windows.
son of parnas
Saturday, February 24, 2007
 
 
Not really, son of parnas.
It will run on any platform which has CLR (the equivalent of JVM); it already does on Windows (.NET), linux (mono) and I believe on Mac too.
It may not support some platform 'extension' but that it the strength of the specification rather than a weakness.
indian
Saturday, February 24, 2007
 
 
indian:
"The most fundamental and defining difference is that C# is a 'pure' OO language while Java is not. Java has primitive types which are not Objects; in C# everything is an Object."

Actually, this isn't quite true. All of the primitive types in C# are implemented as 'structures' (more commonly known as 'structs'). User-defined structs use the same internal .NET plumbing as the primitive structs provided by the framework. The actual *primitive* values in those structs are just implementation details within the runtime.

But since the C# type system includes objects, structures, events, delegates, and pointers, it's a little bit inaccurate to say "everything is an object".
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
Incidentally, here's an article I wrote last year comparing the JVM with the CLR:

http://benjismith.net/index.php/2006/06/23/biz-idea-08-dotjnet-bytecode-translator/

This is a bit outside the scope of the OP's Java vs C# question, but I think a comparison of the runtime implementations is still apropos.
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
Very cool - thanks guys (with a special thanks to BenjiSmith for such an elaborate answer)
FromEmeraldCity Send private email
Saturday, February 24, 2007
 
 
"
Actually, this isn't quite true. All of the primitive types in C# are implemented as 'structures' (more commonly known as 'structs'). User-defined structs use the same internal .NET plumbing as the primitive structs provided by the framework. The actual *primitive* values in those structs are just implementation details within the runtime.

But since the C# type system includes objects, structures, events, delegates, and pointers, it's a little bit inaccurate to say "everything is an object".
"

You are probably correct (as far as C# not being a pure OO lang is concerned) but I am afraid the reasoning you have given is almost entirely incorrect ('almost' because there is no universal consensus on a 'pure' OO language).
I am not intimately familiar with C# specification and don't even use it regularly but I based my reasoning on a discussion with a friend (which was actually on why 'Java is not pure OO' vs say, smalltalk or Eiffel (which are pure OO)) and I remember (or so it seems to me) that every type, including the value types, in C# are derived from the type 'object' and therefore every type is also an object of type Object (which paves way to the concepts of 'boxing' and 'unboxing' etc).
So why am I willing to stand corrected rather than insisting that it is a pure OO?
It is because according to a popular understanding of a pure OO, in a pure OO language there is no way to use a type in a way other than as a object of some class.
Unlike java (where, say int etc are not objects at all) C# does give one the ability to use all types (struts, simple types, events, delegates, anything) as an 'object', the problem is, it just 'doesn't enforces' it.
This subtle difference (which I believe to be true, though again I'm not an expert on the language) makes me willing to stand corrected and accept it as an hybrid language which is very close (compared to C++ or Java) to being a pure OO.
As far as your statement"
"But since the C# type system includes objects, structures, events, delegates, and pointers, it's a little bit inaccurate to say "everything is an object". "

is concerned, I think you are misunderstanding the argument of a pure OO lang and confusing it with 'type-system', which made me say earlier that though I stand corrected, it is for an entirely different argument and a rather subtle (potential) oversight in my reasoning since everything in C# is actually an object (including structs) it is just that they maybe something else 'besides' being an object (e.g int).
If there is some other subtle reasoning I'm missing, I'll be glad to learn about it (I like the lang but never seem to get time to learn about it thoroughly :) )
indian
Saturday, February 24, 2007
 
 
Well I'll be damned. According to the Wikipedia:

"C# has a unified type system. This means that all types, including primitives such as integers, are subclasses of the System.Object class. For example, every type inherits a ToString() method. For performance reasons, primitive types (and value types in general) are internally allocated on the stack. Boxing and unboxing allow one to translate primitive data to and from their object form. Effectively, this makes the primitive types a subtype of the Object type. Primitive types can also define methods (e.g., 42.ToString() calls the ToString() method on an integer), and in the programmer's perspective behave like any other object."

I had no idea that was the case. Cool.
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
@son of parnas: Not having unsigned datatypes makes you jump through hoops for some of the easiest stuff.
I had to convert a lot of checksum algorithms from C++ to Java and this issue is just (unnecessairy, IMO) pain in the back.
asdf Send private email
Saturday, February 24, 2007
 
 
C# doesn't deploy too well to linux. You might say that. If your company for some reason needs many, many servers, C# will cost you plenty.
mynameishere Send private email
Saturday, February 24, 2007
 
 
Unsigned datatypes are particularly nasty when you have to deal with bitwise operations on raw bytes. For example, let's say I want to pack four bytes into an int. With unsigned bytes and an unsigned int, I'd just do this:

ubyte a, b, c, d;
uint abcd =
    ((uint) a << 24) |
    ((uint) b << 16) |
    ((uint) c << 8) |
    ((uint) d);

But with signed types, the bitshifting operations get all screwed up if any of the bytes have a negative value (since the sign bit is sticky). Consequently, the same operation in Java, with only signed types, looks like this:

byte a, b, c, d;
int abcd =
    ((0xff & (char) a) << 24) |
    ((0xff & (char) b) << 16) |
    ((0xff & (char) c) << 8) |
    (0xff & (char) d);

And that's uglier than it ought to be.

Also, you could end up doing some data gymnastics if you ever have to communicate with a system whose protocol includes unsigned types.
BenjiSmith Send private email
Saturday, February 24, 2007
 
 
> linux (mono)

I guess I couldn't put my trust in .net being available on non MS platforms.

> I had to convert a lot of checksum algorithms from C++

Isn't odd to dislike a language because you had a hard time porting one particular algorithm? Wouldn't you also need 128 bit support for SHA and MD5 if you want to go that route?
son of parnas
Saturday, February 24, 2007
 
 
"When the Java classloader accesses classes from a JAR file, it promptly forgets where the classes came from, so it's very difficult at runtime to determine which classes were loaded from which JAR file."

System.out.println(getClass().getClassLoader().getResource("my/pkg/hierarchy/MyClass.class"));

Seems to do a reasonable job of it when I'm trying to figure out if my application is using the wrong jarfile (yey for .JAR hell, much like .DLL hell).

This is more like "Search the classpath until the named resource is found", so might not be a 1:1 mapping of where a class was loaded from (particularly if the classloader's path has changed or you're working from a different classloader than the class you're interested in was loaded from)
Dan Fleet Send private email
Saturday, February 24, 2007
 
 
Just a minor quibble with Benji's post, .NET's BinarySearch does return the insertion point. From MSDN for ArrayList's return value. "The zero-based index of value in the sorted ArrayList, if value is found; otherwise, a negative number, which is the bitwise complement of the index of the next element that is larger than value or, if there is no larger element, the bitwise complement of Count"
brendan Send private email
Sunday, February 25, 2007
 
 
son of parnas

"Isn't odd to dislike a language because you had a hard time porting one particular algorithm? Wouldn't you also need 128 bit support for SHA and MD5 if you want to go that route?"

Beside that the smallest SHA is 160 bits, the answer is No. These algorithms were designed with the practical implementation in mind, thus they are completely based on 32 bit integer operations. Unsigned.

Leaving such a fundamental thing like unsigned integers out of a language is simply braindead. I assume the thought process for this decision went like this, whatever the official statements (which I don't know) purports:

"Hey, we provide our new language with a huuuuuge amount of fancy libraries for all purposes, there will NEVER be a need to write such low level stuff in it. Where did all the good 'ol days went, when 640k ought to be enough for anything?"
Secure
Sunday, February 25, 2007
 
 
Slightly rethinking it, it may not be so braindead after all. Maybe the manager is more braindead who wants to convert low level stuff to a language not supporting it. Depends on the purpose the language was originally designed for.

However, is there one single example of anything software-related that was only used for the purposes it was originally designed for? Torture Excel until it confesses to be a database. ;)
Secure
Sunday, February 25, 2007
 
 
Absolutely nothing. The only difference is the structure of the libraries, and the fact that Java is cross platform, and the nature of the GUI (Java does not have native widgets). They both are capable of the same things, use relatively similar syntax, and rely on a framework. They both have GUI builder IDE's (Eclipse vs. Visual Studio), and the tools are pretty much the same. Java is older, C# is better suited for Windows only development (Mono hasn't advanced that far and its kind of inefficient).

If you know you're only doing Windows then do C# all the time.
Dude Send private email
Sunday, February 25, 2007
 
 
Thanks, brendan!

I wonder where I got the idea from that the C# binarySearch method was substandard. Huh. Maybe version 1.0 of the .NET framework had binarySearch problems. I could have sword I read about that somewhere.
BenjiSmith Send private email
Sunday, February 25, 2007
 
 
+1 warren
lemon obrien Send private email
Sunday, February 25, 2007
 
 
Thanks very much for that excellent rundown of differences, BenjiSmith. I had forgotten a lot of them.
JS
Monday, February 26, 2007
 
 
If this was an interview, Benji would get the job hands down.
OneMist8k
Monday, February 26, 2007
 
 
Woo hoo!!!
BenjiSmith Send private email
Monday, February 26, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz