This is part 1 of a series of articles about Java for C# Programmers.
- I strive to present a terse but complete depiction of the differences between Java and C#, from the point of view of an experienced C# programmer.
- I do not strive to present a a complete reference of the Java language here. A complete reference for Java can be found on http://docs.oracle.com/javase/tutorial/java/.
- Gotcha: Facts that are really unexpected for a C# guy are labeled Gotcha.
How Came?
- Currently, I’m doing a Java course. While learning, I’m writing down what I’ve learned, as a reference for other C# guys and myself.
- Java is a programming language. As such, it is a developer tool. It is public since 1995. A time-tested one, too 😉
Identifiers
In both languages, indentifiers must not start with a number and must not contain spaces. Aside of these rules, most characters are allowed. Including german umlauts ÄÖÜ and currency symbols. Äöüß$$€ is an allowed indentifier.
Naming Conventions
- Classes and interfaces: First letter uppercase. Rest camel cased.
- Packages: lowercased, no _ separators.
package bananaboat;
. When you have a lot of packages, subdivide names by dots.app.boats.bananaboat
- Use pascal cased nouns for class names.
Banana, BookDocument
- Use adjectives for interface names, without leading I.
Eatable, Printable
- Methods: First letter lowercase. Rest camel cased. Verbs.
getPrinter()
- Variables: Like methods.
myFruit
. Use short names for short lived variables.int i
. - Constants: All uppercased, _ as separator.
MAX_WIDTH
Primitive Data Types
It is all the same as in C#, aside of the following differences.
- The unsigned integer types do not exist in Java.
- Gotcha: This means
byte
is signed in Java. - The high precision floating point type
decimal
does not exist in Java. bool
is calledboolean
.- C#’s nullable
bool?
type supports ternary logic with the&
and|
operators. There is no equivalent in Java. - Pointers and tuples do not exist in Java.
- In Java, the primitive types are not derived from object. (In C# they are, via Object -> ValueType -> primitive type.)
- Gotcha: Java’s
Date
is a reference type but C#’sDateTime
a value type. - There is no
TimeSpan
in Java.
Literals
Mostly the same as in C#.
Gotcha: In Java, integer literals starting with a zero are interpreted as octal values. Not so in C#.
int i = 077; // Java: i is 63 decimal
Gotcha: In the following piece of code, the longWithoutL
constant is calculated as int
and then just assigned to the long
. In C#, you’ll get a compile error when making such a mistake.
long longWithL = 1000*60*60*24*365L;
long longWithoutL = 1000*60*60*24*365;
System.out.println(longWithL); // 31536000000
System.out.println(longWithoutL); // 1471228928
Additionally, binary notation for integer type values
is allowed.
int eleven = 0b1011; // 11 decimal
int minuseleven= -0b1011; // -11 decimal
byte minusone = // Compile error. Byte is signed.
0b11111111; // You can use only 7 bits in 0b notation.
byte b = -0b1; // -1 decimal
Wrapper Classes / Boxing / Unboxing
In Java, the primitve types are not derived from Object. Probably because of this, you cannot use them in generics, cannot pass them by reference and they have no methods.
But for every primitive data type, there is a wrapper class which you can use in generics and has generally the same behaviour as the primitive type.
- They are called
Byte, Short, Integer, Long. Float, Double, Boolean. Character
, …. - Automatic conversion to and from the primitive types works well.
- You cannot use these wrapper classes to do a pass by reference for primitive types.
- Some standard functions are implemented on these wrapper classes, e.g.
toString()
.
Java’s Atomic Wrapper Classes
There is another type of wrapper classes available in Java. They are called Atomic Wrapper Classes.
AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
- There is no automatic conversion to and from these types.
- You can change their value and so they can be used for pass by reference of primitive types.
- They are thread safe.
- They implement a lot of functions in an atomic way, like
incrementAndGet(), getAndAdd(int delta)
and the like.
Pass By Ref of Primitive Data Types
static void Test()
{
AtomicInteger i = new AtomicInteger();
i.set(3);
passByRef1(i);
System.out.println("i: " + i); // i: 4
int[] j = { 3 };
passByRef2(j);
System.out.println("j[0]: " + j[0]); // j[0]: 4
Integer k = 3;
passByRefNotGood(k);
System.out.println("k: " + k); // k: 3 **GOTCHA**
}
static void passByRef1(AtomicInteger i)
{
i.incrementAndGet();
}
static void passByRef2(int[] i)
{
i[0]++;
}
static void passByRefNotGood(Integer i)
{
i += 1; // **GOTCHA** This does NOT increment the
// outer Integer, but there's no compile error.
}
Unboxing of Numbers in Calculations
// C#:
int? a = null, c = 3;
int? b = c * a; // b becomes null.
bool? d = false, e = null;
bool? f = d & e; // f becomes false. Ternary logic.
bool? g = d | e; // g becomes null. Ternary logic.
// Java:
Integer a = null, c = 3;
Integer b = c * a; // NullPointerException happens.
Boolean d = false, e = null;
Boolean f = d & e; // NullPointerException.
Magnificent goods from you, man. I’ve understand your stuff previous to and you’re simply too fantastic. I actually like what you have bought right here, really like what you’re stating and the best way during which you assert it. You’re making it entertaining and you continue to take care of to keep it sensible. I cant wait to read far more from you. That is really a terrific web site.