Object-Oriented C Style Languages: C++, Objective-C, Java, C#

a side-by-side reference sheet

grammar and execution | variables and expressions | arithmetic and logic | strings | regexes | dates and time | fixed-length arrays | resizable arrays | tuples | dictionaries | functions | execution control | exceptions | concurrency | file handles | files | file formats | directories | processes and environment | libraries and namespaces | user-defined types | generic types | objects | inheritance and polymorphism | reflection | net and web | unit tests | debugging and profiling

The compiler version used for this sheet.

How to get the compiler version.

Code which examples in the sheet assume to have already been executed.

How to write, compile, and run a "Hello, World!" program.

For source files, header files, and compiled object files.

C++

The gcc compiler will treat a file with any of the following suffixes as C++ source:

.cc .cp .cxx .cpp .CPP .c++ .C

GNU make has built-in rules which treat the following suffixes as C++ source:

.cc .C .cpp

The Google C++ Style Guide recommends that .cc be used as the suffix for C++ source files. Visual Studio uses .cpp as the C++ source file suffix.

One sometimes sees suffixes for headers which distinguish C++ code from C code, but the Google C++ Style Guide and Visual Studio both use .h as the C++ header suffix.

The C++11 standard library uses no suffix at all in headers, at least in the #include statements. This change was made so that the new and the old standard library headers could be distributed together and new headers could have the same basename as the old headers.

How blocks are delimited.

A block contains a sequence of statements. Blocks for function bodies in function definitions; to define the branches of if statements and the bodies of while loops.

Class definition bodies are blocks, though the statements that appear in them are restricted to declarations and definitions.

Bare blocks can be used to limit the scope of variables which are declared inside them.

How statements are terminated.

Statements that can appear at the top level of a source file.

The syntax for a comment which is terminated by the end of the line.

The syntax for a comment which can span multiple lines.

The /* */ delimiters do not nest. Using them to comment out code which already contains a /* */ comment usually results in a syntax error.

How to declare a variable which is allocated on the stack.

The value contained by a local variable that wasn't initialized.

How to declare a global variable.

The value assigned to an uninitialized global variable.

How to declare a constant variable.

How to assign a value to a variable.

The compound assignment operators.

If <OP> is a binary operator and the language has the compound assignment operator <OP>= , then the following are equivalent:

x <OP>= y x = x <OP> y

The C-style increment and decrement operators.

There are prefix (preincrement and predecrement) and postfix (postincrement and postdecrement) versions. The prefix version returns the value after mutation, and the postfix version returns the value before mutation.

c++

Since the compound assignment operators also return the value after mutation, the following are equivalent for primitive types:

cout << ++i << endl; cout << (i += 1) << endl;

The parens are necessary because compound assignment has lower precedence than the << operator.

The caveat about primitive types is necessary because the ++ operator can be overloaded. In fact the prefix and postfix versions can be overloaded separately.

In the case of the the postfix operator, the following are equivalent for primitive types:

cout << i-- << endl; cout << (i += 1, i - 1) << endl;

The compiler may have to allocate a temporary variable to hold the value of i - 1 , which means the postfix version might be slower.

How to get the memory address for a variable. Memory addresses are stored in a type which records the type of the variable whose address was taken.

How to get the value stored at a memory address.

How to get the size of a type in bytes.

How to allocate memory for a primitive type on the heap.

C++

new and delete can be used to manage the memory of both primitive types and objects.

objective c

Object C has a different memory management schemes for primitive types and objects. Objects are allocated with alloc and freed by means of NSAutoreleasePool. For primitive types the same techniques are used as for C. However, idiomatic Objective C will declare primitive types as local variables or as part of the state of an object and avoid explicit calls to malloc.

Arrays of objects can be created with NSArray and NSMutableArray.

java

In Java, arrays are always stored on the heap and the JVM is responsible for garbage collection. The primitive types are stored (1) on the local frame, (2) as part of the state of an object, or (3) as part of the state of a class. The primitive types are never stored in the heap directly and when they are part of object state they are garbage collected with the object. Primitive types are passed by value unless they are encapsulated in an object.

Each of the primitive types has a wrapper class, and instantiating this class is the best approximation in Java to allocating the primitive type on the heap:

Integer i = new Integer(0);

The compiler may instantiate the wrapper class implicitly; this is called boxing. The compiler also permits use of a wrapper class in the place of the primitive type, or unboxing.

C#

C# behavior is like Java. Note that C# lacks specific wrapper classes for each primitive data type.

How to free the memory for a primitive type that was allocated on the heap.

C++

A typical definition:

const int NULL = 0;

The equivalent of the COALESCE function from SQL.

C++, Objective C++:

The short circuit or operator || can be used as a coalesce operator. However, in C++ and Objective C, NULL is identical to zero, whereas in databases they are two distinct values.

Java:

The ternary operator provides the closest approximation to COALESCE, but it does not have the same behavior if the tested value has a side effect.

C

The following definitions are common:

typedef int BOOL; #define TRUE 1 #define FALSE 0

Objective C

From objc.h:

typedef signed char BOOL; #define YES (BOOL)1 #define NO (BOOL)0

C#

bool is an alias for System.Boolean

Literals for the boolean values true and false.

C

The following definitions are common:

typedef int BOOL; #define TRUE 1 #define FALSE 0

Objective C

From objc.h:

typedef signed char BOOL; #define YES (BOOL)1 #define NO (BOOL)0

Values which evaluate as false in the conditional expression of an if statement.

The logical operators.

In all languages on this sheet the && and || operators short circuit: i.e. && will not evaluate the 2nd argument if the 1st argument is false, and || will not evaluate the 2nd argument if the 1st argument is true. If the 2nd argument is not evaluated, side-effects that it contains are not executed.

C++

C++ defines and, or, and not to be synonyms of &&, ||, and !, with the same semantics and precedence.

Java

The arguments of the logical operators must be of type boolean.

C#

The arguments of the logical operators must be of type bool.

Binary operators which return boolean values.

Signed integer types.

C++

Whether char is a signed or unsigned type depends on the implementation.

C#

C# has the following aliases:

sbyte: System.SByte

short: System.Int16

int: System.Int32

long: System.Int64

Unsigned integer types.

C++

Whether char is a signed or unsigned type depends on the implementation.

C#

C# has the following aliases:

byte: System.Byte

ushort: System.UInt16

uint: System.UInt32

ulong: System.UInt64

Floating point types.

C#

C# has the following aliases:

float: System.Single

double: System.Double

Fixed-point decimal types.

C#:

C# has the following alias:

decimal: System.Decimal

The arithmetic binary operators: addition, subtraction, multiplication, division, modulus.

How to get the quotient of two integers.

The results of integer division by zero.

C++, Objective C

The behavior for division by zero is system dependent; the behavior described is nearly universal on Unix.

C#

It is a compilation error to divide by a zero constant. Division by a variable set to zero results in a runtime exception.

How to perform floating point division on two integers.

The result of floating point division by zero.

Modern hardware, if it implements floating point instructions, will implement instructions which conform to the IEEE 754 standard. The standard requires values for positive infinity, negative infinity, and not-a-number (NaN).

The C and C++ standards do not assume that they are running on hardware which provides these values; code which assumes they exist is not strictly speaking portable.

How to perform exponentiation.

C++

powm1 is an abbreviation for "power minus one". Hence the need to add one to get the answer.

The positive square root function.

The result of taking the square root of a negative number.

Here is a list of the standard mathematical functions whose domains do not cover the entire real number line:

function returns inf on returns nan on returns -inf on sqrt inf [-inf, 0) log inf [-inf, 0) 0 asin [-inf, -1) U (1, inf] acos [-inf, -1) U (1, inf]

The exponential and logarithm functions; the trigonometric functions; the inverse trigonometric functions.

The arguments of the trigonometric functions are in radians as are the return values of the inverse trigonometric functions.

The transcendental constants e and pi.

Functions for converting a float to a nearby integer value.

C:

The math.h library also provides floor and ceil which return double values.

Java:

Math.floor and Math.ceil return double values.

The absolute value of a numeric quantity.

What happens when an integer expression results in a value larger than what can be stored in the integer type.

What happens when a float expression results in a value larger than largest representable finite float value.

The largest finite floating point number and the smallest positive floating point number.

How to construct a complex number.

How to get the components of a complex number. Both Cartesian and polar decompositions are illustrated. Also how to get the complex conjugate.

Ways to generate random numbers. The distributions are a uniform integer from 0 to 99; a uniform float from 0.0 to 1.0; a standard normal float.

c++:

The standard library includes functions for generating random numbers from other distributions.

How to set the seed for the random number generator.

The bit operators: left shift, right shift, and, or, xor, and complement.

C++

bitand, bitor, and compl are synonyms of &, |, and ~ with identical precedence and semantics.

Binary, octal, and hex integer literals.

How to convert integers to strings of digits of a given base. How to convert such strings into integers.

The type for strings.

The syntax for string literals.

Can a newline be used in a string literal? Does the newline appear in the resulting string object?

Escape sequences that can be used in string literals.

How to allocate a string.

Java

The following code

String t = new String(s);

creates a copy of the string s. However, because Java strings are immutable, it would be safe to store the same string object it t as follows:

String t = s;

C++

string::compare returns a positive value, 0, or a negative value depending upon whether the receiver is lexicographically greater, equal, or less than the argument. C++ overload the comparison operators (<, >, ==, !=, <=, >=) so that they can be used for string comparison.

Objective C

compare will return -1, 0, or 1.

Java

compareTo will return a negative value, 0, or a positive value.

C#

CompareTo will return -1, 0, or 1.

C++

strtoimax, strtol, strtoll, strtoumax, strtoul, and strtoull take three arguments:

intmax_t strtoimax(const char *str, char **endp, int base);

The 2nd argument, if not NULL, will be set to first character in the string that is not part of the number. The 3rd argument can specify a base between 2 and 36.

strtof, strtod, and strtold take three arguments:

double strtod(const char *str, char **endp);

Java

parseInt has an optional second argument for the base.

java:

Use StringBuilder to implement join:

public static String join(String[] a, String sep) { StringBuilder sb = new StringBuilder(); for (int i=0; i<a.length; i++) { if (i > 0) { sb.append(sep); } sb.append(a[i]); } return sb.toString(); }

regex match

regex substitute

The data type used to store a combined date and time.

How to get the current date and time.

How to convert a date/time object to the Unix epoch. How to convert the Unix epoch to a date/time object.

The Unix epoch is the number of seconds since 1 January 1970 UTC.

c#:

Windows file time is the number of nanoseconds since 1 January 1601 UTC divided by 100. The concept was introduced when journaling was added to NTFS with Windows 2000.

The magic constant (11644473600) used for the conversion can be calculated with the following code:

using System; using System.Globalization; CultureInfo enUS = new CultureInfo("en-US"); DateTime startEpoch = DateTime.ParseExact( "1970-01-01 00:00:00 -00", "yyyy-MM-dd HH:mm:ss zz", enUS); Console.WriteLine(startEpoch.ToFileTimeUtc() / (10 * 1000 * 1000));

How to use a format string to display a date/time object.

The canonical example of doing this is the strftime function from the C standard library which defines used letters prefix by percent signs as conversion specification characters, e.g. %Y-%m-%d.

How to use a format string to parse date data from a string.

How to allocate an array which is freed when the block in which it is defined goes out of scope.

How to allocate an array on the heap.

How to free an array that was allocated on the heap.

Objective C

NSArray can only store instances of NSObject. For primitive types, use C arrays.

Java

Java permits arrays to be declared with C-style syntax:

int a[] = {1,2,3}

How to get the size of a fixed-length array.

How to get the value stored at an index in a fixed-length array.

C++

Arrays can be manipulated with pointer syntax. The following sets x and y to the same value:

int a[] = {3,7,4,8,5,9,6,10}; int x = a[4]; int y = *(a+4);

How to update the value stored at an index in a fixed-length array.

What happens when an out-of-bounds index is used to access a value in a fixed-length array.

How to copy a fixed-length array.

How to pass a fixed-length array as a function argument.

How to iterate over the values of the fixed-length array.

C++

Range-based for loops can be used with fixed-length arrays (but not pointers):

int a[4] = {3, 2, 4, 1}; int sum(0); for (const auto& n: a) { sum += n; }

How to iterate over a resizable array.

C++

The range-based for loop was introduced in C++11. It it can be used to iterate over an initialization list:

for (const auto& n: {1, 2, 3}) { sum += n; }

pair

map declaration

C:

For those interested in an industrial strength hashtable implementation for C, here is the header file and the source file for the hashtable used by Ruby.

For those interested in a "Computer Science 101" implementation of a hashtable, here is a simpler source file and header file.

map access

map size

map remove

map element not found result

map iterator

How to declare the type of a function.

How to define a function.

How to invoke a function.

Objective C:

Named parameters must be invoked in the order in which they are defined in the method signature.

C#:

Named parameter do not need to be invoked in the order in which they are defined in the method signature. Additionally, their use in

invocation is optional: the arguments can be provided without names in which case the definition order must be used.

C++

A note on how to overload postfix and prefix ++ and — .

The syntax for an if statement.

The curly braces around the branches of an if statement are optional when the branch contains a single statement.

From the perspective of the parser, the branches are statements. Curly branch delimited blocks are legal wherever a statement is legal.

When if statements are nested and the outer if statement does not put its if-clause in curly braces, the parser will match a subsequent else to the inner if . Code which puts the else on the same level of indentation as the outer if is deceptive.

The syntax for a switch statement.

A switch checks the value of integer expression and jumps to the correct label. This can faster than an if statement with numerous else if branches which tests the expression until a match is found.

Execution falls through to code after subsequent labels unless a break statement is encountered. This makes it possible to write code once which handles multiple values.

The syntax for a while loop.

If the body of a while loop is a single statement, the curly braces are optional.

The languages in this sheet also have a do-while loop, which is a loop which always executes at least once.

Here is an example of a do-while loop which converts an unsigned integer to a string. The corresponding while loop would require extra handling when the integer is zero.

/* unsigned int n; * char* s; */ do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0); s[i] = '\0'; reverse(s);

The syntax for a C-style for loop.

The parens of the for loop contain three expressions set off by semicolons: the initialization, the condition, and the increment.

The initialization expression executes once before the loop starts.

The condition expression executes once before the start of each iteration. The loop stops if the condition is false.

The increment executes at the end of each iteration.

The break statement terminates execution of the innermost containing loop or switch statement.

A method for breaking out of nested loops.

The continue statement, which terminates execution of the current loop iteration.

The base class or interface for exceptions.

A partial list of exceptions raised by the language or the standard library.

How to raise an exception.

C++

C++ code can throw or catch any type of object or primitive data type. The C++ standard library throws subclasses of std::exception, which does not have a message member.

Objective C

Objective C can only throw an instance of NSException or one of its subclasses.

Java

Java can only throw an implementation of java.lang.Throwable.

C#

C# can only throw an instance of System.Exception of one of its subclasses.

How to handle an exception.

C++

Exceptions can be caught by value or by reference. If the exception is an object and it is caught by value, the copy constructor and the destructor will be invoked.

Objective C

Exceptions are thrown and caught by pointer value.

How to define a new exception type.

How to handle and re-raise an exception.

How to write a handler witch catches any exception.

C++

Class Finally { void (*finally)(); Finally(void (*f)()) : finally(f) { } ~Finally() { do_cleanup(); } }; { Cleanup c(); risky(); }

Java

If a method throws a subclass of java.lang.Exception, it must declare the exception in its throws clause. This includes exceptions originating in code called by the method. On the other hand, if the method throws a subclass of java.lang.Error, no declaration in the throws clause is necessary.

How to print a formatted string to standard out.

read from file

C

If there is an error, the global variable errno will be set to a nonzero value, and strerror(errno) will return an error message for the error.

write to file

signature of main

first argument

C

The first argument is the pathname to the executable. Whether the pathname is absolute or relative depends on how the executable was invoked. If the executable was invoked via a symlink, then the first argument is the pathname of the symlink, not the executable the symlink points to.

environment variable

iterate through environment variables

The name of the standard library.

C++

Standard Template Library (STL)

The STL might not be installed by default.

Objective C

Foundation Framework

The Foundation Framework is the core of Cocoa, a set of libraries for Objective C development on Mac OS X and the iPhone. The Foundation Framework descends from NextStep, hence the NS prefix in the class names. NextStep was made available to operating systems other than Next as OpenStep and the GNU implementation is called GNUStep.

Java

Java 1.6 API

C#

.NET Framework 4 Class Library

Mono Documentation

The core of the .NET framework is called the Base Class Library. Mono implements the BCL, but not all of the .NET framework.

C

Because C integer types don't have well defined sizes, typedef is sometimes employed to as an aid to writing portable code. One might include the following in a header file:

typedef int int32_t;

The rest of the code would declare integers that need to be 32 bits in size using int32_t and if the code needed to be ported to a platform with a 16 bit int, only a single place in the code requires change. In practice the typedef abstraction is leaky because functions in the standard library such as atoi, strtol, or the format strings used by printf depend on the underlying type used.

Java

Java has well defined integer sizes so typedef is not needed as a portability aid. In other situations where a C programmer would use a typedef for data abstraction, a Java programmer must either define a class or retain the raw primitive type throughout the code.

C

Enums were added to the C standard when the language was standardized by ANSI in 1989.

An enum defines a family of integer constants. If an integer value is not explicitly provided for a constant, it is given a value one greater than the previous constant in the list. If the first constant in the list is not given an explicit value, it is assigned a value of zero. it is possible for constants in a list to share values. For example, in the following enum, a and c are both zero and b and d are both one.

enum { a=0, b, c=0, d };

A typedef can be used to make the enum keyword unnecessary in variable declarations:

typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week; day_of_week d = tue;

From the point of view of the C compiler, an enum is an int. The C compiler does not prevent assigning values to an enum type that are not in the enumerated list. Thus, the following code compiles:

enum day_of_week { mon, tue, wed, thu, fri, sat, sun }; day_of_week d = 10; typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week2; day_of_week2 d2 = 10;

C++

C++ enums are more strongly typed the C enums. The compiler rejects attempts to assign a value to an enum variable that is not in the enumerated list. The following code:

enum day_of_week { mon, tue, wed, thu, fri, sat, sun }; day_of_week d = 10;

produces an error like the following:

main.cpp: In function ‘int main()’: main.cpp:21: error: invalid conversion from ‘int’ to ‘main()::day_of_week’

Java

Java added enums in 1.5.

Java enums are strongly typed like C++ enums. Unlike C++ enums, it is an error to use an enum value in an integer context. The value has a method ordinal() which returns the integer value, however.

When used in a string context, an enum will evaluate as the string corresponding to its identifier: i.e. "TUE" for DayOfWeek.TUE. This string can be accessed explicitly with DayOfWeek.TUE.toString(). Conversely, DayOfWeek.valueOf("TUE") returns DayofWeek.TUE.

Java enums are subclasses of java.lang.Enum. In particular, an enum is a class, and if the last value if the enum definition is followed by a semicolon, what follows is a class body which can contain methods and constructors. An enum class is final and cannot be subclassed, but an enum can implement an interface.

C#

Like Java enums, C# enums will return the string corresponding to their identifier. Unlike Java enums, C# enums will evaluate as integers in a numeric context.

When used as an argument in a C# style format string, an enum value returns the string corresponding to its identifier.

struct definition

A struct provides names for elements in a predefined set of data and permits the data to be accessed directly without the intermediation of getters and setters. C++, Java, and C# classes can be used to define structs by making the data members public. However, public data members violates the uniform access principle.

C++:

From The C++ Programming Language: 3rd Edition:

by definition, a struct is a class in which members are by default public; that is, struct s { ... is simply shorthand for class s { public: ...

struct declaration

struct initialization

C

The literal format for a struct can only be used during initialization. If the member names are not provided, the values must occur in the order used in the definition.

struct member assignment

struct member access

C

The period operator used for member access has higher precedence than the pointer operator. Thus parens must be used

to get at the member of a struct referenced by a pointer:

struct medal_count { char* country; int gold; int silver; int bronze; } struct medal_count spain = { "Spain", 3, 7 4 }; struct medal_count *winner = &spain; printf("The winner is %s with %d gold medals", (*winner).country, (*winner).gold);

ptr->mem is a shortcut for (*ptr).mem:

printf("The winner (%s) earned %d silver medals", winner->country, winner->silver);

define generic type

instantiate generic type

define class

constructor

create object

destructor

C++

The C++ compiler will normally see to it that the destructor for a class and all its superclasses is called. The compiler may not be aware of the true class of the object if it was upcast to one of its base class. If the destructor was not declared virtual, then the derived class destructor and any other base class constructors will not get called. Thus many developers declare all destructors virtual.

Java

Java does not chain finalize() methods, so the derived class should explicitly call the parent.

destroy object

Java

finalize() is called by the Java garbage collector.

define method

invoke method

define class method

invoke class method

name of receiver

access control

objective c:

Access control only applies to members; all methods are public. gcc 4.0 does not enforce the access restrictions; it merely gives warnings.

anonymous class

dynamic dispatch

static dispatch

Method dispatch is static if the method is determined by the variable type, and dynamic if it is determined by the value type. These techniques of method dispatch yield different results when both the base class and the derived class have implementations for a method, and an instance of the derived class is being stored in a variable with type of the base class.

When dispatch is static, the compiler can determine the code that will be executed for the method call. When dispatch is dynamic, the code that will be executed is a runtime decision. C++ implementations usually achieve this by storing function pointers in the object: qv virtual method table.

The use of the keyword static in the declaration of a class method in C++, Java, and C# is perhaps unfortunate. Class methods are always statically dispatched, so the concepts are not unrelated.

subclass

superclass constructor

mark class underivable or method overrideable

root class

Name of the root class, if there is one.

objective c:

It is possible to define a root class other than NSObject.

root class methods

A selection of methods available on the root class.

get type class of object

get type class from string

get type class from type identifier

c++:

typeid returns a value of type type_info. The assignment method and copy constructor of type_info are private.

class name

*c++:**

The string returned by type_info.name() contains more than the class name. The code below displayed the string "Z4mainE3Foo" when run on my system.

class Foo { int i; }; puts(typeid(Foo).name());

get methods

has method

invoke method object

How to URL encode and URL decode a string.

URL encoding is also called percent encoding. It is used to escape special characters in GET query string parameters.

Reserved characters according to RFC 3986 are replaced by a percent sign % followed by a two hex digit representation of the ASCII code. The reserved characters are:

! * ' ( ) ; : @ & = + $ , / ? # [ ]

Spaces can optionally be represented by a plus sign +.

C++11 Standard (pdf)

Standard C++ Library Reference

The GNU C++ Library

Google C++ Style Guide

Designing Qt-Style C++ APIs

C++11 and gcc

gcc provides a C++11 compiler which will run on Linux, Mac OS X, and Windows. For a complete implementation of the C++11 standard one should use gcc 4.8 or later, but gcc 4.6 is sufficient for the examples in this sheet. Support for C++11 features must be requested with the -std=c++0x flag.

C++11 on Mac OS X

The version of gcc that comes with XCode in Mac OS X 10.8 as part of the command line tools package is 4.2. This version of gcc does not support C++11, but the command line tools package also provides the clang compiler which does:

clang++ -std=c++11 -stdlib=libc++ -o hello hello.cpp

Like gcc , clang does not compile C++11 by default, hence the -std=c++11 flag. One must also specify the C++ standard library, since the libc++ library which comes with clang will support C++11, but the libstdc++ library provided with gcc 4.2 will not, and clang uses the gcc library by default.

C++11 Windows

The Visual Studio 2012 C++ compiler does not completely support C++11, but it has support for the features mentioned in this sheet. For a complete C++11 compiler, install MinGW and gcc 4.8.

Compatibility with C

What's New in C++11

Programming with Objective-C Apple

GNUstep

Mac OS X Foundation Framework

Java 1.6 API

JDK 7 Project

JVM Specification 2nd Ed

The Java Language Specification 3rd Ed

A Java program is created from source code via an explicit compilation step using javac . The executable is then launched using the virtual machine java . Both javac and java use the Java runtime jar rt.jar , which contains the Java standard libraries.

$ ls -l $(which javac) -rwxrwxr-x 1 root wheel 99296 Oct 8 2013 /Library/JVM/jdk7.0/Contents/Home/bin/javac $ ls -l $(which java) -rwxrwxr-x 1 root wheel 99216 Oct 8 2013 /Library/JVM/jdk7.0/Contents/Home/bin/java $ ls -l $JAVA_HOME/jre/lib/rt.jar -rw-rw-r-- 1 root wheel 64181940 Oct 8 2013 /Library/JVM/jdk7.0/Contents/Home/jre/lib/rt.jar $ cat Main.java public class Main { public static void main(String[] argv) throws Throwable { System.out.println("Hello, World!"); } } $ javac Main.java $ ls -l Main.class -rw-r--r-- 1 hpglot staff 463 Dec 27 06:12 Main.class $ java Main Hello, World!

Using dtruss on Mac OS X to verify that javac and java use rt.jar :

$ sudo dtruss javac Main.java 2>&1 | grep -E '^open' | grep rt.jar open("/Library/JVM/jdk7.0/Contents/Home/jre/lib/rt.jar\0", 0x0, 0x0) = 4 0 $ sudo dtruss java Main 2>&1 | grep -E '^open' | grep rt.jar open("/Library/JVM/jdk7.0/Contents/Home/jre/lib/rt.jar\0", 0x0, 0x0) = 4 0

C# Standard: ECMA-334

Mono API

C# Programming Guide Microsoft