string
is an alias in C# for System.String
.
So technically, there is no difference. It's like int
vs. System.Int32
.
As far as guidelines, it's generally recommended to use string
any time you're referring to an object.
e.g.
string place = "world";
Likewise, I think it's generally recommended to use String
if you need to refer specifically to the class.
e.g.
string greet = String.Format("Hello {0}!", place);
This is the style that Microsoft tends to use in their examples.
It appears that the guidance in this area may have changed, as StyleCop now enforces the use of the C# specific aliases.
The name reflection is used to describe code which is able to inspect other code in the same system (or itself).
For example, say you have an object of an unknown type in Java, and you would like to call a 'doSomething' method on it if one exists. Java's static typing system isn't really designed to support this unless the object conforms to a known interface, but using reflection, your code can look at the object and find out if it has a method called 'doSomething' and then call it if you want to.
So, to give you a code example of this in Java (imagine the object in question is foo) :
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
One very common use case in Java is the usage with annotations. JUnit 4, for example, will use reflection to look through your classes for methods tagged with the @Test annotation, and will then call them when running the unit test.
There are some good reflection examples to get you started at http://docs.oracle.com/javase/tutorial/reflect/index.html
And finally, yes, the concepts are pretty much similar in other statically typed languages which support reflection (like C#). In dynamically typed languages, the use case described above is less necessary (since the compiler will allow any method to be called on any object, failing at runtime if it does not exist), but the second case of looking for methods which are marked or work in a certain way is still common.
Update from a comment:
The ability to inspect the code in the system and see object types is
not reflection, but rather Type Introspection. Reflection is then the
ability to make modifications at runtime by making use of
introspection. The distinction is necessary here as some languages
support introspection, but do not support reflection. One such example
is C++
Best Answer
There are a lot of similarities between both implementations (and in my opinion: yes, they're both "virtual machines").
For one thing, they're both stack-based VM's, with no notion of "registers" like we're used to seeing in a modern CPU like the x86 or PowerPC. The evaluation of all expressions ((1 + 1) / 2) is performed by pushing operands onto the "stack" and then popping those operands off the stack whenever an instruction (add, divide, etc) needs to consume those operands. Each instruction pushes its results back onto the stack.
It's a convenient way to implement a virtual machine, because pretty much every CPU in the world has a stack, but the number of registers is often different (and some registers are special-purpose, and each instruction expects its operands in different registers, etc).
So, if you're going to model an abstract machine, a purely stack-based model is a pretty good way to go.
Of course, real machines don't operate that way. So the JIT compiler is responsible for performing "enregistration" of bytecode operations, essentially scheduling the actual CPU registers to contain operands and results whenever possible.
So, I think that's one of the biggest commonalities between the CLR and the JVM.
As for differences...
One interesting difference between the two implementations is that the CLR includes instructions for creating generic types, and then for applying parametric specializations to those types. So, at runtime, the CLR considers a List<int> to be a completely different type from a List<String>.
Under the covers, it uses the same MSIL for all reference-type specializations (so a List<String> uses the same implementation as a List<Object>, with different type-casts at the API boundaries), but each value-type uses its own unique implementation (List<int> generates completely different code from List<double>).
In Java, generic types are a purely a compiler trick. The JVM has no notion of which classes have type-arguments, and it's unable to perform parametric specializations at runtime.
From a practical perspective, that means you can't overload Java methods on generic types. You can't have two different methods, with the same name, differing only on whether they accept a List<String> or a List<Date>. Of course, since the CLR knows about parametric types, it has no problem handling methods overloaded on generic type specializations.
On a day-to-day basis, that's the difference that I notice most between the CLR and the JVM.
Other important differences include:
The CLR has closures (implemented as C# delegates). The JVM does support closures only since Java 8.
The CLR has coroutines (implemented with the C# 'yield' keyword). The JVM does not.
The CLR allows user code to define new value types (structs), whereas the JVM provides a fixed collection of value types (byte, short, int, long, float, double, char, boolean) and only allows users to define new reference-types (classes).
The CLR provides support for declaring and manipulating pointers. This is especially interesting because both the JVM and the CLR employ strict generational compacting garbage collector implementations as their memory-management strategy. Under ordinary circumstances, a strict compacting GC has a really hard time with pointers, because when you move a value from one memory location to another, all of the pointers (and pointers to pointers) become invalid. But the CLR provides a "pinning" mechanism so that developers can declare a block of code within which the CLR is not allowed to move certain pointers. It's very convenient.
The largest unit of code in the JVM is either a 'package' as evidenced by the 'protected' keyword or arguably a JAR (i.e. Java ARchive) as evidenced by being able to specifiy a jar in the classpath and have it treated like a folder of code. In the CLR, classes are aggregated into 'assemblies', and the CLR provides logic for reasoning about and manipulating assemblies (which are loaded into "AppDomains", providing sub-application-level sandboxes for memory allocation and code execution).
The CLR bytecode format (composed of MSIL instructions and metadata) has fewer instruction types than the JVM. In the JVM, every unique operation (add two int values, add two float values, etc) has its own unique instruction. In the CLR, all of the MSIL instructions are polymorphic (add two values) and the JIT compiler is responsible for determining the types of the operands and creating appropriate machine code. I don't know which is the preferably strategy, though. Both have trade-offs. The HotSpot JIT compiler, for the JVM, can use a simpler code-generation mechanism (it doesn't need to determine operand types, because they're already encoded in the instruction), but that means it needs a more complex bytecode format, with more instruction types.
I've been using Java (and admiring the JVM) for about ten years now.
But, in my opinion, the CLR is now the superior implementation, in almost every way.