Comparing C# and Java
Pages: 1, 2, 3, 4
The is and as Operators
The is operator in C# is the same as the instanceof operator in Java. Both can be used to test whether or not an instance of an object is of a particular type. The as operator in C# has no equivalent in Java. It is very similar to the is operator, but it is more aggressive in that it also tries to convert the tested object reference into the type in question, if the type is correct. If not, the variable reference will be set to null.
To really understand how as operates, consider the use of is in the following code, where there is an interface called IShape and two classes (Rectangle and Circle) that both implement IShape.
using System;
interface IShape {
void draw();
}
public class Rectangle: IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
public class Circle: IShape {
public void draw() {
}
public int GetRadius() {
return 5;
}
}
public class LetsDraw {
public static void Main(String[] args) {
IShape shape = null;
if (args[0] == "rectangle") {
shape = new Rectangle();
}
else if (args[0] == "circle") {
shape = new Circle();
}
if (shape is Rectangle) {
Rectangle rectangle = (Rectangle) shape;
Console.WriteLine("Width : " + rectangle.GetWidth());
}
if (shape is Circle) {
Circle circle = (Circle) shape;
Console.WriteLine("Radius : " + circle.GetRadius());
}
}
}
After the code is compiled, the user can enter either "rectangle" or "circle" as a shape in args[0] of the Main method. If "circle" is entered, shape is then instantiated to a Circle object. On the other hand, if the user types in "rectangle," shape is instantiated to a Rectangle. The shape is then tested for its object type using the is operator. If it is a rectangle, then shape is cast to a Rectangle object and its GetWidth method is called. If it is a circle, shape is cast to a Circle object and its GetRadius method is called.
Using the as operator, the example code above can be modified as in the following.
using System;
interface IShape {
void draw();
}
public class Rectangle: IShape {
public void draw() {
}
public int GetWidth() {
return 6;
}
}
public class Circle: IShape {
public void draw() {
}
public int GetRadius() {
return 5;
}
}
public class LetsDraw {
public static void Main(String[] args) {
IShape shape = null;
if (args[0] == "rectangle") {
shape = new Rectangle();
}
else if (args[0] == "circle") {
shape = new Circle();
}
Rectangle rectangle = shape as Rectangle;
if (rectangle != null) {
Console.WriteLine("Width : " + rectangle.GetWidth());
}
else {
Circle circle = shape as Circle;
if (circle != null)
Console.WriteLine("Radius : " + circle.GetRadius());
}
}
}
In the bold lines in the code above, as is used to convert shape to Rectangle without first testing its object type. If shape is indeed a Rectangle, shape is cast into rectangle as a Rectangle object and its GetWidth method is called. If the conversion fails, a second attempt is performed. This time, shape is cast into circle as a Circle object. If shape is really a Circle object, circle will now reference to the Circle object and its GetRadius method is invoked.
Libraries
C# does not have its own class libraries. However, it shares the .NET class libraries that can be used in other .NET languages such as VB.NET or JScript.NET. Something worth noting is the StringBuilder class, which complements the String class. The StringBuilder class is very similar to Java's StringBuffer.
Garbage Collection
C++ has taught us how inefficient and time-consuming it is to deal with memory management manually. When you create an object in C++, you have to destroy it manually. As code becomes more complex, this task becomes increasingly difficult. Java solved this problem using the garbage collection method that collects unused objects and releases the memory. C# follows suit; however, this is a very natural path to take if you are developing a new OOP language. C# still preserves the C++ way of managing memory manually when speed is in extreme need, something which is taboo in Java.
Exception Handling
You would not be surprised to find out that C# uses an error handling mechanism similar to Java's, would you? In C# all exceptions are derived from the class named Exception. (Aha, why does this sound familiar?) And, yes, you have the familiar try and catch statement like in Java. This Exception class is part of the .NET System namespace.
What Java Does Not Have
Born after Java was already mature, it is no surprise that C# has some nice features that Java does not have (yet).
Enumerators (enums)
An enumerator is a set of related constants. To be exact, an enum type declaration defines a type name for a related group of symbolic constants. For example, you can create an enumerator called Fruit and use it as the value type of a variable to limit the possible values of the variable to those specified in the enumerator.
public class Demo {
public enum Fruit {
Apple, Banana, Cherry, Durian
}
public void Process(Fruit fruit) {
switch (fruit) {
case Fruit.Apple:
...
break;
case Fruit.Banana:
...
break;
case Fruit.Cherry:
...
break;
case Fruit.Durian:
...
break;
}
}
}
In the Process method of the example above, surely you can use an int as the value type of the myVar variable. However, using the enum Fruit limits the possible values to Apple, Banana, Cherry or Durian. Compared to int, enum is more readable and self-documenting.
Structs
A struct is very similar to a class. However, while a class is created in the heap as a reference type, a struct is a value type that is stored on the stack or in-line. Therefore, used with care, structs are faster than classes. A struct can implement interfaces and have the same kinds of members as a class, but a struct does not support inheritance.
However, simply replacing a class with a struct can be disastrous. Because a struct is passed by value, a "fat" struct is slower to pass around because values must be copied to a new place. In the case of a class, only the reference to the class is passed around.
The following is an example of a struct. Note how similar it is with a class. Substituting the word "class" for "struct" gives you a class.
struct Point {
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Properties
In addition to fields, a C# class can also have properties. A property is a named attribute associated with an object or a class. Properties are a natural extension of fields -- both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the statements to execute in order to read or write their values. Properties thus provide a mechanism for associating actions with the reading and writing of an object's attributes, and they furthermore permit such attributes to be computed.
In C#, properties are defined using property declaration syntax. The first part of the syntax looks quite similar to a field declaration. The second part includes a get accessor and/or a set accessor. In the example below, the PropertyDemo class defines a Prop property.
public class PropertyDemo {
private string prop;
public string Prop {
get {
return prop;
}
set {
prop = value;
}
}
}
Properties that can be read and written, like the Prop property in the PropertyDemo class, include both get and set accessors. The get accessor is called when the property's value is read; the set accessor is called when the property's value is written. In a set accessor, the new value for the property is given in an implicit value parameter.
A property can be read and written in the same way that fields can be read and written. For example, the following code instantiates the PropertyDemo class and writes and reads its Prop property.
PropertyDemo pd = new PropertyDemo();
pd.Prop = "123"; // set
string s = pd.Prop; // get
Passing Primitive Parameters By Reference
In Java, when you pass a primitive as a parameter to a method, the parameter is always passed by value -- i.e., a new copy of the parameter is created for that method. In C#, you can pass a primitive (value type) by reference. If you do this, the method uses the same variable passed to it -- i.e., if you change the value of the value type passed, the original variable is changed.
To pass a value type by reference in C#, you use the keyword ref. For example, if you compile and run the following C# code, you will get 16 in the console. Note how the value of i is changed after being passed to the ProcessNumber method.
using System;
public class PassByReference {
public static void Main(String[] args) {
int i = 8;
ProcessNumber(ref i);
Console.WriteLine(i);
}
public static void ProcessNumber(ref int j) {
j = 16;
}
}
There is also another keyword named out. This is similar to ref, allowing a value type to be passed by reference; however, the variable passed as the parameter does not have to have a known value before the passing. The example above will generate an error message if the int i is not initialized before being passed to the ProcessNumber method. If you use out instead of ref, you can pass a value that has not been initialized, like in the following modified example.
using System;
public class PassByReference {
public static void Main(String[] args) {
int i;
ProcessNumber(out i);
Console.WriteLine(i);
}
public static void ProcessNumber(out int j) {
j = 16;
}
}
This time the class PassByReference compiles fine, even though i is not initialized prior to passing it to the method ProcessNumber.
Pointers Are Still Available in C#
Developers who think they can handle pointers wisely and are happy with manual memory management can get some extra horsepower in performance by using the "old time" pointers which are neither safe nor easy. C# provides the ability to write "unsafe" code. Such code can deal directly with pointer types, and fix objects to temporarily prevent the garbage collector from moving them. This "unsafe" code feature is in fact a "safe" feature from the perspective of both developers and users. Unsafe code must be clearly marked in the code with the modifier unsafe, so developers can't possibly use unsafe features accidentally, and the C# compiler and the execution engine work together to ensure that unsafe code cannot masquerade as safe code.
using System;
class UsePointer {
unsafe static void PointerDemo(byte[] arr) {
.
.
.
}
}
Unsafe code is used in C# when speed is extremely important or when your object needs to interface with existing software, such as COM objects or native C code in DLLs.
Delegates
Delegates can be thought of as function pointers in C++ and other languages. Unlike function pointers, however, delegates in C# are object-oriented, type-safe, and secure. And, while a function pointer can only be used to reference a static function, a delegate can reference both a static method and an instance method. A delegate is used to encapsulate a callable method. You can write a method in a class and create a delegate on that method. The delegate can then be passed to a second method. This second method can then call the first method.
Delegates are reference types that derive from a common base class: System.Delegate. There are three steps in defining and using delegates: declaration, instantiation, and invocation. Delegates are declared using the delegate declaration syntax. A delegate that takes no arguments and returns void can be declared with the following code.
delegate void TheDelegate();
A delegate instance can be instantiated using the new keyword, and referencing either an instance or class method that conforms to the signature specified by the delegate. Once a delegate has been instantiated, it can be called using method call syntax.
Boxing and Unboxing
In an object-oriented language, you normally work with objects, but primitives are also provided for the sake of speed, so you have a world of objects and another world of values. In this situation there is always a need to make both worlds able to work together. You invariably need a way to make references and values communicate.
In C# and .NET Runtime worlds, this "communication" problem is solved using boxing and unboxing. Boxing is a process to make value types look like reference types. Boxing happens automatically when a value type (a primitive) is used in a location that requires or could use an object. Boxing a value of a value-type consists of allocating an object instance and copying the value-type value into that instance.
Unboxing does the reverse of what boxing does. It converts a reference type into a value type. An unboxing operation consists of first checking that the object instance is a boxed value of the given value-type, and then copying the value out of the instance.
Java tackles this problem somewhat differently by providing a class wrapper for each primitive, e.g. the Integer class for int and the Byte class for byte.
Summary
This article has shown you how C# and Java compare. They are very similar; however, it is probably too far to say that C# is a clone of Java. Things like object-orientation or intermediary languages are not new ideas. So, if you were to design a new object-oriented language that needs to run in a managed and safe environment, wouldn't you come up with something like C#?
Budi Kurniawan is a senior J2EE architect and author.
Return to .NET DevCenter.
Showing messages 1 through 23 of 23.
-
C# alpha-convertible to Java
2003-12-16 06:02:46 anonymous2 [Reply | View]
Well ... at least almost. There is some requirements for Beta-conversion when converting "readonly" to static final [...] and maybe some other syntactic differences. Of course, things like pointers aren't convertible - but since only C++ programmers would use them in a language like Java/C# anyways, it's less of a problem.
Oh, and someone stated that the "switch" statement doesn't exist in Java - it does and works just fine!
-
C# and java
2003-09-18 11:50:58 anonymous2 [Reply | View]
MANY DEVELOPERS THINK THAT C# IS BETTER THAN JAVA AND THAT IT OFFERS MANY NEW AND ADVANCE FEATURES IF SO THAN WHY DO YOU ALL .NET DEVELOPERS AND SPECIALLY MICROSOFT NEED JAVA AS PART OF IT'S .NET PLATFORM?
THE FACT IS THAT MICROSOFT NEEDS JAVA AND THAT C# WAS A POOR ATTEMPT OF CLONING JAVA.
HAVING SAID THAT I HONESTLY THINK THAT THERE IS NO REPLACEMENT OF JAVA AND THAT JAVA WILL REMAIN THE PRIMARY LANGUAGE TO DEVELOPE WEBSERVICES AS WELL AS OTHER WEB ENABLED APPLICATIONS
-
C# and java
2003-09-18 11:50:35 anonymous2 [Reply | View]
MANY DEVELOPERS THINK THAT C# IS BETTER THAN JAVA AND THAT IT OFFERS MANY NEW AND ADVANCE FEATURES IF SO THAN WHY DO YOU ALL .NET DEVELOPERS AND SPECIALLY MICROSOFT NEED JAVA AS PART OF IT'S .NET PLATFORM?
THE FACT IS THAT MICROSOFT NEEDS JAVA AND THAT C# WAS A POOR ATTEMPT OF CLONING JAVA.
HAVING SAID THAT I HONESTLY THINK THAT THERE IS NO REPLACEMENT OF JAVA AND THAT JAVA WILL REMAIN THE PRIMARY LANGUAGE TO DEVELOPE WEBSERVICES AS WELL AS OTHER WEB ENABLED APPLICATIONS
-
c# for java programmers
2002-12-30 06:39:04 anonymous2 [Reply | View]
I have read a lot of articles on how c# is or is not like java but I think until you start to code C# you don't really notice the differences between the two languages.
C# is a newer language and thus necessarily has new features. The question is will they help or not. Here is my list of things that give me problems:
1. namespaces, packages and assemblies. Everyone says the that a package and a namespace is the same and so is an assembly. But they are not the same thing. Packages in Java determine the fully qualified names of classes and also determine class/method/field accessiblity for package accessibility. No matter how you deliver your classes (i.e. what classes you make available in your jar) your package accessibility does not change. With C#, namespace is just a text prefix to the name of a class and has nothing to do with accessiblity. So you can't use a namespace to hide a method from a set of classes. Further, the "internal" accessibility modifier changes with respect to how you create your dll's. So this is not like package visibility either.
The result is in java you might have lots of packages and you often put everything in 1 big jar, while in .NET you are going to have lots of dll's with few namespaces each. Otherwise you will be exposing too much functionality in the "internal" "namespace".
2. I have trouble with delegates being an "object oriented" function wrapper. The idea being a function wrapper and object oriented seem to be incompatible. I may just be getting old, but I don't think delegates are an advancement in the right direction. I think the idea of interfaces to implement the publish/subscribe (observer) pattern is not bad and I must say I prefer the publish/subscribe pattern of java to the callback techniques of, say, Xlib. It seems delegate are just a return to the old callback functions.
3. I miss anonymous inner classes. Why didn't they put this in c#. They provide a very elegant technique for solving a lot of common implementation problems. I suppose that delegates are suppose to take up the slack here, but (as I said before), I don't much care for delegates.
So in total, while C# does provide some new features - some good (like foreach, and using) it also has some less good features (for example, I think attributes make the job of tool vendors easier, but just polutes good application code with cryptic compiler directives). What we need are articles that are neither anti-c# nor (and there are a lot of these) pure microsoft marketing talk. We also need a good set of standard c# idioms and best practices (without the marketing).
-
Anders ideas are Pre-Java
2002-09-10 16:10:13 anonymous2 [Reply | View]
It worths remebering that Anders used to work in a language that had many of these features/keywords a long time ago, before Java exists. Delphi has single inheritance/multiple interface design, most of class isolation concepts of C#, properties, the "using" keyword ("uses" in Delphi) and many others I canīt remember now. So these are not Java concepts at all, neither C# (some of them) ones.
-
Is there a winner as far as reliability is concerned?
2002-06-24 09:28:12 webguy197 [Reply | View]
Forgive me, as a Web programmer who only knows a little bit of Java... I wanted to ask, does anyone have an opinion as to the reliability of C++/C# vs. Java? I ask because it has been my experience with web Applets and Java Server pages that they are occasionally "buggy" on a windows platform. I could not say whether C++/C# is any better, or whether the buggyness is just a result of the web.
-
C# is clearly better
2001-08-22 11:09:08 graygoo [Reply | View]
The designers of Java do not embrace change. Microsoft seems to be willing to move forward with languages by adding features that programmers really want. If Java does not add features to its language often enough, it will become a dead language just like Wordperfect, NeXT and many other non-microsoft products. There is no way Java can compete with an evolving language just like there is in way to compete with Microsoft's other products.
Don't get trapped by Java.
-
Pointers Secure?
2001-06-27 04:59:18 criecke [Reply | View]
So someone can write "unsafe" code that utilizes pointers. How long do you think it'll take for someone to write a C# virus?
But it's probably a moot point. Beyond all technical issues is the fact that you must pay for C#, but Java is free. In this economic climate, for my company the choice is a no-brainer.
-
Poor execution of plagiarism
2001-06-25 13:50:08 gckleon [Reply | View]
MS's recipe for doing it right:
Start off with Java.
Add a couple of minor enhancements (wrapped
primitives, enums, inventing new control
statements for things easily done with "for"
statements etc.), mix in some major digressions (optional manual memory management and pointers), sprinkle with redundant support for already trivially accomplished concepts (like properties), change some of the syntax for absolutely no good reason ("is" instead of "instanceof", ":" instead of "extends", etc. etc.), and finally, rip everything else off.
Nicely done !
-
Poor execution of plagiarism
2004-12-25 22:56:01 musnat [Reply | View]
Microsoft bashing comments are great way of showing why C# is really much better than any language out there, not Java only.
Microsoft bashing is also a great way to show what an idiot you are. Nobody would want to hire idiots who lack the intelligence to explain what he thinks and why.
Nicely done gckleon
-
Reflection in in C#
2001-06-14 21:56:44 techforesee [Reply | View]
Hi,
The article does not talk about reflection ability that java has. Has C# has reflection ability?
Reflection ability is useful in developing generic frameworks.
-techforesee
-
Another view
2001-06-13 11:25:07 ftcmj [Reply | View]
For another review of the C# language, see my articles in JavaWorld from November and December of last year:
C#: A language alternative or just J--?
Part 1: http://www.javaworld.com/javaworld/jw-11-2000/jw-1122-csharp1.html
Part 2: http://www.javaworld.com/javaworld/jw-12-2000/jw-1222-csharp2.html
C# vs. Java: a debate
http://www.javaworld.com/javaworld/jw-11-2000/jw-1122-letters_p.html
After reviewing the language carefully, I believe that while C# has some differences from Java, it essentially targets the same space, and provides real value only to people locked into the Windows platform. There are some neat features, and some IMHO really stupid features; in particular, the absence of mandatory exception declarations is a major blunder.
Of all the C# features, I think automatic primitive wrapping (boxing and unboxing) is the only one that might improve Java. The rest are fluff. But none of these new features make C# a fundamentally different language, in my opinion. C# gives Microsoft a Java-like language (and a developer and customer base) that they can control.
--Mark Johnson
-
Another view
2004-12-25 23:00:07 musnat [Reply | View]
I believe you are simply lying to us about java and c#.
Java is owned by Sun, whereas C# is an ISO standard. While Java programmers are programming into propietary language, C# programmers program with an open standard language.
The fact that Mark Johnson lies do not change any of these facts. Would anybody believe in an author writing for javaworld? Ofcourse he is going to lie.
-
Some thoughts...
2001-06-11 20:57:29 skawai [Reply | View]
From page 2
Constants:
readonly something like final?
(only in Java, you cat set it anywhere)
The entry point of a public class:
drupp527 alreadly stated it...
The switch statement:
I've always wondered why Java didn't
implement this feature. I mean, you
could use Object#equals()...
From page 3
goto:
That's the last thing you want in an
OO language.
From page 4
Properties:
Maybe JavaBeans?
-
error handling not THAT different
2001-06-11 08:03:58 tgke [Reply | View]
I don't agree with the last row in the comparison of the three languages. C++ supports exception handling quite well, and Stroustrup describes explicitly how to use them.
Both Java and C# do support error handling with return values as well, this all depends on the programmer, and is not promoted nor hindered by the two languages.
-
Minor correction
2001-06-08 12:39:07 drupp527 [Reply | View]
On page 2, in the discussion of "The entry point of a public class", the author states "As a comparison, overloading the main method is illegal in Java." This is not quite true.
It *is* true (as I suspect the author intended to explain) that overloaded main() methods in Java cannot be entry points to the class. Only the method with the specific signature "public static void main(String args [])" can serve as the entry point. The specification of the single argument "args" may vary slightly, but it must be of type String[] (an array of Strings). Other definitions of methods named "main" may exist, including those with different visibility levels, parameter lists, and return types. Such methods behave as would comparable methods with other names.
A class is not required to have a "public static void main(...)" method. Such a class is perfectly valid; it just cannot be excercised directly from the command line.
What you can't do in Java is specify two methods with the same name and signature (number, type, and order of arguments) with different return types. I don't have access to a C# compiler, but I suspect this would cause problems in C# as well.






The protected keyword is really very different in java and c# as in java it allows access to other members of the same package and to subclasses and in c# it only allows access to subclasses. Yeah?
The internal keyword in c# restricts access to the assembly, but this has no bearing on the namespace.
Java really has a fouth access modifier, the 'not-specified' access modifer which resricts access to the package. In many ways I think this is most useful one.
By not allowing us to restrict access to classes in the same namespace/package, doesn't this more or less defeat the point of putting them in different namespaces in the first place?
I feel i must be missing or misunderstanding something...