Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Comparison of C Sharp and Java
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Object-oriented programming == Both C# and Java are designed from the ground up as [[Object-oriented programming|object-oriented]] languages using [[dynamic dispatch]], with syntax similar to [[C++]] (C++ in turn [[Compatibility of C and C++|derives]] from [[C (programming language)|C]]). Neither language is a superset of C or C++, however. {| class="wikitable" style="width:80%;" |- ! style="width:40%;"| Object orientation!! style="width:30%;"|Java !! style="width:30%;"|C# |- |[[Class (computer programming)|Classes]] || {{yes|mandatory}} || {{yes|mandatory}} |- |[[Interface (object-oriented programming)|Interfaces]] || {{yes}} || {{yes}} |- |[[Class (computer programming)#Abstract and concrete|Abstract classes]] || {{yes}} || {{yes}} |- |Member accessibility levels || {{yes|public, package, protected, private}} || {{yes| public, internal, protected, private, protected internal}} |- |Class-level [[Class (computer programming)#Local and inner|inner classes]] || {{yes}} || {{yes}} |- |Instance-level inner classes || {{yes}} || {{no}} |- |Statement-level (local) [[Class (computer programming)#Unnamed|anonymous classes]] || {{yes}} || {{yes|Yes; but without methods| style=background: #8CF;}} |- |[[Partial class]]es || {{no | style=background: #8CF;}}; Third-party library<ref>[[AspectJ|Extension created for the Java programming language]]</ref> || {{yes}} |- |Implicit (inferred) anonymous classes || {{ No| style=background: #8CF;}}; Not needed|| {{yes}}<ref>{{cite web |url=https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/anonymous-types |title=Anonymous Types (C# Fundamentals) |publisher=learn.microsoft.com |access-date=14 April 2013}}</ref> |- |[[Deprecation]]/obsolescence || {{yes}} || {{yes}} |- |Overload versioning || {{some}} || {{yes}} |- | [[Enumerated type|Enums]] can implement [[Interface (object-oriented programming)|interfaces]] || {{yes}} || {{no}} |- |[[Property (programming)|Properties]] || {{no}} || {{yes}} |- |[[Event (computing)|Events]] || {{yes|Provided by standard libraries}} || {{yes|Built-in language feature}} |- |[[Operator overloading]] || {{no}} || {{yes}} |- |Indexers || {{no}} || {{yes}} |- |Implicit conversions || {{no | style=background: #8CF;}}; but see [https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html autoboxing] || {{yes}} |- |Explicit conversions || {{yes}} || {{yes}} |} === Partial class === C# allows a class definition to be split across several source files using a feature called ''partial classes''. Each part must be marked with the keyword {{mono|partial}}. All the parts must be presented to the compiler as part of a single compilation. Parts can reference members from other parts. Parts can implement interfaces and one part can define a base class. The feature is useful in code generation scenarios (such as [[user interface]] (UI) design), where a code generator can supply one part and the developer another part to be compiled together. The developer can thus edit their part without the risk of a code generator overwriting that code at some later time. Unlike the class extension mechanism, a partial class allows ''circular'' dependencies among its parts as they are guaranteed to be resolved at compile time. Java has no corresponding concept. === Inner and local classes === Both languages allow ''inner classes'', where a class is defined lexically inside another class. However, in each language these inner classes have rather different semantics. In Java, unless the inner class is declared {{mono|static}}, a reference to an instance of an inner class carries a reference to the outer class with it. As a result, code in the inner class has access to both the static and non-static members of the outer class. To create an instance of a non-static inner class, the instance of the embracing outer class must be named.<ref name="inner instance creation">{{cite web |url=http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#41147 |title=Java SE Specifications |publisher=Java.sun.com |access-date=24 February 2015}}</ref> This is done via a new {{mono|new}}-operator introduced in JDK 1.3: {{code|outerClassInstance.new Outer.InnerClass()}}. This can be done in any class that has a reference to an instance of the outer class. In C#, an inner class is conceptually the same as a normal class. In a sense, the outer class only acts as a namespace. Thus, code in the inner class cannot access non-static members of the outer class unless it does so through an explicit reference to an instance of the outer class. Programmers can declare the inner class ''private'' to allow only the outer class to have any access to it. Java provides another feature called ''local classes'' or ''anonymous classes'', which can be defined within a method body. These are generally used to implement an interface with only one or two methods, which are typically event handlers. However, they can also be used to override virtual methods of a superclass. The methods in those local classes have access to the outer method's local variables declared {{mono|final}}. C# satisfies the use-cases for these by providing anonymous [[Delegate (CLI)|delegates]]; see [[#Event|event handling]] for more about this. C# also provides a feature called ''anonymous types/classes'', but it is rather different from Java's concept with the same name. It allows the programmer to instantiate a class by providing only a set of names for the properties the class should have, and an expression to initialize each. The types of the properties are inferred from the types of those expressions. These implicitly-declared classes are derived directly from ''object''. === Event === C# multicast-delegates are used with ''events''. Events provide support for [[event-driven programming]] and are an implementation of the [[observer pattern]]. To support this there is a specific syntax to define events in classes, and operators to register, unregister or combine event handlers. See [[#Delegates, method references|here]] for information about how events are implemented in Java. === Operator overloading and conversions === [[Operator overloading]] and user-defined [[type conversion|casts]] are separate features that both aim to allow new types to become first-class citizens in the type system. By using these features in C#, types such as [[Complex numbers|{{mono|Complex}}]] and [[decimal128|{{mono|decimal}}]] have been integrated so that the usual operators like addition and multiplication work with the new types. Unlike C++, C# does restrict the use of operator overloading, prohibiting it for the operators {{mono|new}}, {{code|( )}}, {{code|{{!}}{{!}}}}, {{code|&&}}, {{code|{{=}}}}, and any variations of compound statements like {{code|+{{=}}}}. But compound operators will call overloaded simple operators, like {{code|-{{=}}}} calling {{code|-}} and {{code|{{=}}}}.<ref name="nested">{{cite web |url=http://www.25hoursaday.com/ |title=A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: Operator Overloading |author=Dare Obasanjo |year=2007 |publisher=Dare Obasanjo |archive-url=https://web.archive.org/web/20120919093308/http://25hoursaday.com/ |archive-date=19 September 2012 |quote=Note: Unlike C++, C# does not allow the overloading of the following operators; {{mono|1=new, ( ), ||, &&, =}}, or any variations of compound assignments such as {{mono|1=+=, -=}}, etc. However, compound assignment operators will call overloaded operators, for instance, {{mono|1=+=}} would call overloaded {{mono|1=+}}. |access-date=6 September 2012 |url-status=dead |df=dmy-all}}</ref> Java does not include operator overloading, nor custom conversions to prevent abuse of the feature and to keep the language simple.<ref>{{cite web |url=http://www.cafeaulait.org/1998august.html |title=Java News from August, 1998 |publisher=Cafeaulait.org |access-date=24 February 2015}}</ref> === Indexer === C# also includes ''indexers'' that can be considered a special case of operator overloading (like the C++ {{code|operator[]}}), or parameterized {{mono|get}}/{{mono|set}} properties. An indexer is a property named {{code|this[]}} that uses one or more parameters (indexes); the indices can be objects of any type: <syntaxhighlight lang="csharp"> myList[4] = 5; string name = xmlNode.Attributes["name"]; orders = customerMap[theCustomer]; </syntaxhighlight> Java does not include indexers. The common Java pattern involves writing explicit getters and setters where a C# programmer would use an indexer. === Fields and initialization === {| class="wikitable" style="width:80%;" |- ! style="width:40%;"| Fields and initialization !! style="width:30%;"|Java !! style="width:30%;"|C# |- |[[Field (computer science)|Fields]] || {{yes}} || {{yes}} |- |[[Constant (programming)|Constants]] || {{yes}} || {{yes}}; but no support for constant passed parameters<ref name="final">{{cite web |url=http://csunwold.blogspot.co.at/2010/02/from-stackoverflow-im-looking-for-c.html |title=C# Equivalent to Java's "final" |last1=Sunwold |first1=Corey |date=25 February 2010 |publisher=Corey Sunwold |archive-url=https://archive.today/20121129011204/http://csunwold.blogspot.co.at/2010/02/from-stackoverflow-im-looking-for-c.html |url-status=live |archive-date=29 November 2012 |quote=There is than one use of the final keyword that C# does not have an equivalent for. When you pass a parameter to a method in Java, and you don't want that parameter's value to change within the scope of that method you can set it as final like this: |access-date=13 September 2016 }}</ref> |- |Static (class) [[Constructor (object-oriented programming)|constructors]] || {{yes}} || {{yes}} |- |Instance constructors || {{yes}} || {{yes}} |- |[[Destructor (computer science)|Finalizers/destructors]] || {{yes}} || {{yes}} |- |Instance initializers || {{yes}} || {{no}}; can be simulated with instance constructor |- |Object [[Initialization (programming)|initialization]] || {{yes|Bottom-up <br/>(fields and constructors)}} || {{yes|Top-down (fields); bottom-up (constructors)}} |- |Object initializers || {{yes}} || {{yes}} |- |Collection initializers || {{yes|Static varargs methods}} || {{yes}} |- |Array initializers || {{yes}} || {{yes}} |} ==== Object initialization ==== In both C# and Java, an object's fields can be initialized either by ''variable initializers'' (expressions that can be assigned to variables where they are defined) or by ''constructors'' (special subroutines that are executed when an object is being created). In addition, Java contains ''instance initializers'', which are anonymous blocks of code with no arguments that are run after the explicit (or implicit) call to a superclass's constructor but before the constructor is executed. C# initializes object fields in the following order when creating an object: # Derived static fields # Derived static constructor # Derived instance fields # Base static fields # Base static constructor # Base instance fields # Base instance constructor # Derived instance constructor Some of the above fields may not be applicable (e.g. if an object does not have ''static fields''). ''Derived fields'' are those that are defined in the object's direct class, while ''base field'' is a term for the fields that are defined in one of the object's superclasses. Note that an object representation in memory contains all fields defined in its class or any of its superclasses, even, if some fields in superclasses are defined as private. It is guaranteed that any field initializers take effect before any constructors are called, since both the instance constructor of the object's class and its superclasses are called after field initializers are called. There is, however, a potential trap in object initialization when a virtual method is called from a base constructor. The overridden method in a subclass may reference a field that is defined in the subclass, but this field may not have been initialized because the constructor of the subclass that contains field initialization is called after the constructor of its base class. In Java, the order of initialization is as follows: # Invocation of another constructor (either of the object's class or of the object's superclass) # Instance variable initializers and instance initializers (in the order they appear in the source code) # The constructor body Like in C#, a new object is created by calling a specific constructor. Within a constructor, the first statement may be an invocation of another constructor. If this is omitted, the call to the argumentless constructor of the superclass is added implicitly by the compiler. Otherwise, either another overloaded constructor of the object's class can be called explicitly, or a superclass constructor can be called. In the former case, the called constructor will again call another constructor (either of the object's class or its subclass) and the chain sooner or later ends up at the call to one of the constructors of the superclass. After another constructor is called (that causes direct invocation of the superclass constructor, and so forth, down to the Object class), instance variables defined in the object's class are initialized. Even if there are no variable initializers explicitly defined for some variables, these variables are initialized to default values. Note that instance variables defined in superclasses are already initialized by this point, because they were initialized by a superclass constructor when it was called (either by the constructor's code or by variable initializers performed before the constructor's code or implicitly to default values). In Java, variable initializers are executed according to their textual order in the source file. Finally, the constructor body is executed. This ensures proper order of initialization, i.e. the fields of a base class finish initialization before initialization of the fields of an object class begins. There are two main potential traps in Java's object initialization. First, variable initializers are expressions that can contain method calls. Since methods can reference any variable defined in the class, the method called in a variable initializer can reference a variable that is defined below the variable being initialized. Since initialization order corresponds to textual order of variable definitions, such a variable would not be initialized to the value prescribed by its initializer and would contain the default value. Another potential trap is when a method that is overridden in the derived class is called in the base class constructor, which can lead to behavior the programmer would not expect when an object of the derived class is created. According to the initialization order, the body of the base class constructor is executed before variable initializers are evaluated and before the body of the derived class constructor is executed. The overridden method called from the base class constructor can, however, reference variables defined in the derived class, but these are not yet initialized to the values specified by their initializers or set in the derived class constructor. The latter issue applies to C# as well, but in a less critical form since in C# methods are not overridable by default. === Resource disposal === Both languages mainly use [[garbage collection (computer science)|garbage collection]] as a means of reclaiming memory resources, rather than explicit deallocation of memory. In both cases, if an object holds resources of different kinds other than memory, such as file handles, graphical resources, etc., then it must be notified explicitly when the application no longer uses it. Both C# and Java offer interfaces for such deterministic [[dispose pattern|disposal]] and both C# and Java (since Java 7) feature automatic resource management statements that will automatically invoke the disposal/close methods on those interfaces. === Methods === {| class="wikitable" style="width:80%;" |- ! style="width:40%;"| Methods and properties !! style="width:30%;"|Java !! style="width:30%;"|C# |- |Static imports || {{yes}} || {{yes}}<ref>{{cite web |url=https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/may/csharp-a-csharp-6-0-language-preview |title=C# – A C# 6.0 Language Preview |date=July 2015 |publisher=learn.microsoft.com |access-date=14 April 2023}}</ref> |- |Virtual methods|| {{yes|Virtual by default}} || {{yes|Non-Virtual by default}} |- |[[Abstraction (computer science)|Abstract]] || {{yes}} || {{yes}} |- |Sealing || {{yes}} || {{yes}} |- |Explicit interface implementation || {{yes|Default methods}} || {{yes}}<ref name="interface">{{cite web |url=http://www.25hoursaday.com/CsharpVsJava.html#explicitinterface |title=A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 15. Explicit Interface Implementation |author=Dare Obasanjo |year=2007 |publisher=Dare Obasanjo |archive-url=https://web.archive.org/web/20120922081727/http://www.25hoursaday.com/CsharpVsJava.html#explicitinterface |archive-date=22 September 2012 |access-date=11 September 2012 |url-status=live |df=dmy-all}}</ref> |- |Value (input) parameters || {{yes}} || {{yes}} |- |Reference (input/output) parameters || {{no}} || {{yes}} |- |Output (output) parameters || {{no}} || {{yes}} |- |Constant (immutable) parameters || {{yes}}; [[#Constant/immutable parameters|final]] parameters || {{yes}}<ref>{{cite web |url=https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier |title=in parameter modifier (C# Reference) |date=5 March 2018 |publisher=Microsoft |archive-url=https://archive.today/20190126124708/https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier |url-status=live |archive-date=26 January 2019 |access-date=26 January 2019}}</ref> |- |[[Variadic function|Variadic methods]] || {{yes}} || {{yes}} |- |Optional arguments || {{no}};<ref>{{cite web | last1=Gosling|first1=James |title=The Java® Language Specification |url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1 |access-date=5 October 2014|location=Section 8.4.1. Formal Parameters}}</ref> Instead method overloading or varargs || {{yes}} |- |Named arguments || {{yes}}; with annotations || {{yes}} |- |[[Generator (computer programming)|Generator methods]] || {{no | style=background: #8CF;}}; but see [[Generator (computer programming)#Java|Stream Api]] || {{yes}} |- |Extension/default methods || {{yes}} || {{yes}} |- |Conditional methods || {{no}} || {{yes}} |- |Partial methods || {{no}} || {{yes}} |} ==== Extension methods and default methods ==== Using a special ''this'' designator on the first parameter of a method, C# allows the method to act as if it were a member method of the type of the first parameter. This ''extension'' of the foreign class is purely syntactical. The extension method must be declared {{mono|static}} and defined within a purely static class. The method must obey any member access restriction like any other method external to the class; thus static methods cannot break object encapsulation.<ref>{{cite web | url=http://www.hanselman.com/blog/HowDoExtensionMethodsWorkAndWhyWasANewCLRNotRequired.aspx | title=How do Extension Methods work and why was a new CLR not required? | first=Scott|last=Hanselman | date=4 April 2008 | quote=''Extension methods are a really nice syntactic sugar. They're not really added to the class, as we can see, but the compiler makes it feel like they are'' | access-date=29 March 2014}}</ref><ref>{{cite web | url=http://msdn.microsoft.com/en-us//library/bb383977.aspx | title=Extension Methods (C# Programming Guide) | publisher=[[Microsoft]] | year=2013 | quote=''Extension methods are defined as static methods but are called by using instance method syntax'' | access-date=29 March 2014}}</ref> The "extension" is only active within scopes where the namespace of the static host class has been imported. Since Java 8, Java has a similar feature called ''default methods'', which are methods with a body declared on interfaces. As opposed to C# extension methods, Java default methods are instance methods on the interface that declare them. Definition of default methods in classes that implement the interface is optional: If the class does not define the method, the default definition is used instead. Both the C# extension methods and the Java default methods allow a class to override the default implementation of the extension/default method, respectively. In both languages this override is achieved by defining a method on the class that should use an alternate implementation of the method. C# scope rules defines that if a matching method is found on a class, it takes precedence over a matching extension method. In Java any class declared to implement an interface with default method is assumed to have the default methods implementations, ''unless'' the class implements the method itself. ==== Partial methods ==== Related to ''partial classes'' C# allows partial methods to be specified within partial classes. A partial method is an intentional declaration of a method with several restrictions on the signature. The restrictions ensure that if a definition is not provided by any class part, then the method and every call to it can be safely erased.<ref>{{cite web |title=C# Language Specification Version 4.0 |url=http://www.microsoft.com/en-us/download/details.aspx?id=7029 |publisher=Microsoft |access-date=10 May 2012 |page=281 |quote=If no part of a partial type declaration contains an implementing declaration for a given partial method, any expression statement invoking it is simply removed from the combined type declaration. Thus the invocation expression, including any constituent expressions, has no effect at run-time. The partial method itself is also removed and will not be a member of the combined type declaration. If an implementing declaration exist for a given partial method, the invocations of the partial methods are retained. The partial method gives rise to a method declaration similar to the implementing partial method declaration except for the following: […]}}</ref> This feature allows code to provide a large number of interception points (like the [[Template method pattern|template method]] [[Design Patterns|GoF]] design pattern) without paying any runtime overhead if these extension points are not being used by another class part at compile time. Java has no corresponding concept. ==== Virtual methods ==== ''Methods'' in C# are non-[[Virtual function|virtual]] by default, and must be declared virtual explicitly, if desired. In Java, all non-static non-private methods are virtual. Virtuality guarantees that the most recent [[Method overriding (programming)|override]] for the method will always be called, but incurs a certain runtime cost on invocation as these invocations cannot be normally [[Inline expansion|inlined]], and require an indirect call via the [[virtual method table]]. However, some JVM implementations, including the Oracle reference implementation, implement inlining of the most commonly called virtual methods. Java methods are virtual by default (although they can be ''sealed'' by using the {{mono|final}} modifier to disallow overriding). There is no way to let [[Subclass (computer science)|derived classes]] define a new, unrelated method with the same name. This means that by default in Java, and only when explicitly enabled in C#, new methods may be defined in a derived class with the same name and signature as those in its base class. When the method is called on a superclass reference of such an object, the "deepest" overridden implementation of the [[base class]]' method will be called according to the specific subclass of the object being referenced. In some cases, when a subclass introduces a method with the same name and signature as a method already present in the [[base class]], problems can occur. In Java, this will mean that the method in the derived class will implicitly override the method in the base class, even though that may not be the intent of the designers of either class. To mitigate this, C# requires that if a method is intended to override an inherited method, the {{mono|override}} keyword must be specified. Otherwise, the method will "hide" the inherited method. If the keyword is absent, compiler warning to this effect is issued, which can be silenced by specifying the {{mono|new}} keyword. This avoids the problem that can arise from a base class being extended with a non-private method (i.e. an inherited part of the namespace) whose signature is already in use by a derived class. Java has a similar compiler check in the form of the {{code|@Override}} method annotation, but it is not compulsory, and in its absence, most compilers will not provide comment (but the method will be overridden). ==== Constant/immutable parameters ==== In Java, it is possible to prevent reassignment of a local variable or method parameter by using the {{Java|final}} keyword. Applying [[final (Java)#Final variables|this keyword]] to a primitive type variable causes the variable to become immutable. However, applying {{Java|final}} to a reference type variable only prevents that another object is assigned to it. It will not prevent the data contained by the object from being mutated. As of {{not a typo|C#7}}, it is possible to prevent reassignment of a method parameter by using the {{mono|in}} keyword, however this keyword cannot be used on local variables. As with Java, applying {{mono|in}} to a parameter only prevents the parameter from being reassigned to a different value. It is still possible to mutate the data contained by the object.<ref name="in">{{cite web |url=https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier |title=in parameter modifier (C# Reference) |date=5 March 2018 |publisher=Microsoft |archive-url=https://archive.today/20190126124708/https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier |url-status=live |archive-date=26 January 2019 |quote=The in keyword causes arguments to be passed by reference. It is like the ref or out keywords, except that in arguments cannot be modified by the called method. |access-date=26 January 2019 }}</ref> {| class="wikitable" |- ! Java !! C# |- | <syntaxhighlight lang="java"> public int addOne(final int x) { x++; // ERROR: a final variable cannot be reassigned return x; } public List addOne(final List<Integer> list) { list.add(1); // OK: it is still possible to modify a // final (reference type) variable return list; }</syntaxhighlight> || <syntaxhighlight lang="csharp"> public int AddOne(in int x) { x++; // ERROR: a readonly parameter cannot be reassigned return x; } public List<int> AddOne(in List<int> list) { list.Add(1); // OK: it is still possible to modify a // readonly (reference type) parameter return list; } </syntaxhighlight> |} Both languages do not support essential feature of [[const-correctness]] that exists in [[C (programming language)|C]]/[[C++]], which makes a method constant. Java defines the word "constant" arbitrarily as a {{Java|static final}} field. As a convention, these variable names are capital-only with words separated with an [[underscore]] but the Java language doesn't insist on this. A parameter that is only {{Java|final}} is not considered as a constant, although it may be so in the case of a [[primitive data type]] or an [[immutable class]], like a {{Java|String}}. ==== Generator methods ==== {{further|Generator (computer programming)}} Any C# method declared as returning {{mono|IEnumerable}}, {{mono|IEnumerator}} or the generic versions of these interfaces can be implemented using {{mono|yield}} syntax. This is a form of limited, compiler-generated continuations and can drastically reduce the code needed to traverse or generate sequences, although that code is just generated by the compiler instead. The feature can also be used to implement infinite sequences, e.g., the sequence of [[Fibonacci numbers]]. Java does not have an equivalent feature. Instead, generators are typically defined by providing a specialized implementation of a well-known collection or iterable interface, which will compute each element on demand. For such a generator to be used in a ''for each'' statement, it must implement interface {{Javadoc:SE|package=java.lang|java/lang|Iterable}}. See also example [[#Fibonacci sequence|Fibonacci sequence]] below. ==== Explicit interface implementation ==== C# also has ''explicit interface implementation'' that allows a class to specifically implement methods of an [[Interface (object-oriented programming)|interface]], separate to its own class methods, or to provide different implementations for two methods with the same name and signature inherited from two base interfaces. In either language, if a method (or property in C#) is specified with the same name and signature in multiple interfaces, the members will clash when a class is designed that implements those interfaces. An implementation will by default implement a common method for all of the interfaces. If separate implementations are needed (because the methods serve separate purposes, or because return values differ between the interfaces) C#'s explicit interface implementation will solve the problem, though allowing different results for the same method, depending on the current cast of the object. In Java there is no way to solve this problem other than refactoring one or more of the interfaces to avoid name clashes.<ref name="interface" /> ==== Reference (in/out) parameters ==== The arguments of primitive types (e.g. int, double) to a method are passed by value in Java whereas objects are passed by reference. This means that a method operates on copies of the primitives passed to it instead of on the actual variables. On the contrary, the actual objects in some cases can be changed. In the following example, object String is not changed. Object of class 'a' is changed. In C#, it is possible to enforce a reference with the {{mono|ref}} keyword, similar to C++ and in a sense to C. This feature of C# is particularly useful when one wants to create a method that returns more than one object. In Java trying to return multiple values from a method is unsupported unless a wrapper is used, in this case named "Ref".<ref>{{cite web |url=http://www.25hoursaday.com/ |title=A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language: D. Now for Something Completely Different: 12. Pass by Reference |author=Dare Obasanjo |year=2007 |publisher=Dare Obasanjo |archive-url=https://web.archive.org/web/20120919093308/http://25hoursaday.com/ |archive-date=19 September 2012 |quote=In Java the arguments to a method are passed by value meaning that a method operates on copies of the items passed to it instead of on the actual items. In C#, as in C++ and in a sense C, it is possible to specify that the arguments to a method actually be references to the items being passed to the method instead of copies. This feature is particularly useful when one wants to create a method that returns more than one object. In Java trying to return multiple values from a method is unsupported and leads to anomalies like: a method that swaps two numbers that have been the hallmark of freshman computer science classes for years, is impossible to do in Java without resorting to coding tricks. |access-date=10 September 2012 |url-status=dead |df=dmy-all}}</ref> {| style="width:100%; border:none;" class="wikitable" |- !width=50%| Java !! style="width:50%;"| C# |- valign=top | <syntaxhighlight lang="java" style="font-size:95%"> class PassByRefTest { static class Ref<T> { T val; Ref(T val) { this.val = val; } } static void changeMe(Ref<String> s) { s.val = "Changed"; } static void swap(Ref<Integer> x, Ref<Integer> y) { int temp = x.val; x.val = y.val; y.val = temp; } public static void main(String[] args) { var a = new Ref(5); var b = new Ref(10); var s = new Ref("still unchanged"); swap(a, b); changeMe(s); System.out.println( "a = " + a.val + ", " + "b = " + b.val + ", " + "s = " + s.val ); } } </syntaxhighlight> | <syntaxhighlight lang="csharp" style="font-size:95%"> class PassByRefTest { public static void ChangeMe(out string s) { s = "Changed"; } public static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; } public static void Main(string[] args) { int a = 5; int b = 10; string s = "still unchanged"; Swap(ref a, ref b); ChangeMe(out s); System.Console.WriteLine("a = " + a + ", " + "b = " + b + ", " + "s = " + s); } }</syntaxhighlight> |- valign=top | {{code|1=a = 10, b = 5, s = Changed}} || {{code|1=a = 10, b = 5, s = Changed}} |} === Exceptions === {| class="wikitable" style="width:80%;" |- ! style="width:40%;"| Exceptions !! style="width:30%;"|Java !! style="width:30%;"|C# |- |Checked exceptions || {{yes}} || {{no}} |- |Try-catch-finally || {{yes}} || {{yes}} |- |Exception filters || {{no}} || {{yes}}<ref>{{cite web |url=https://www.pluralsight.com/guides/exceptional-exception-filtering |title=Exceptional Exception Filtering |publisher=Pluralsight® |access-date=24 June 2022}}</ref> |} ====Checked exceptions==== Java supports [[checked exceptions]] (along with unchecked exceptions). C# only supports unchecked exceptions. Checked exceptions force the programmer to either declare the exception thrown in a method, or to catch the thrown exception using a {{tt|try-catch}} clause. Checked exceptions can encourage good programming practice, ensuring that all errors are dealt with. However [[Anders Hejlsberg]], chief C# language architect, argues that they were to some extent an experiment in Java and that they have not been shown to be worthwhile except in small example programs.<ref>{{cite web |url=http://www.artima.com/intv/handcuffs.html |title=The Trouble with Checked Exceptions |publisher=Artima.com |access-date=24 February 2015}}</ref><ref>{{cite web |url=http://msdn2.microsoft.com/en-us/vcsharp/aa336812.aspx |title=Msdn forums – Visual C# Language |publisher=Msdn2.microsoft.com |access-date=24 February 2015 |archive-url=https://web.archive.org/web/20070320060200/http://msdn2.microsoft.com/en-us/vcsharp/aa336812.aspx |archive-date=20 March 2007 |url-status=dead}}</ref> One criticism is that checked exceptions encourage programmers to use an empty catch block ({{java|catch (Exception e) {}|}}),<ref name=bruceeckel>{{cite web |last=Eckel |first=Bruce |url=http://www.mindview.net/Etc/Discussions/CheckedExceptions |title=Does Java need Checked Exceptions? |access-date=6 December 2012 |archive-url=https://web.archive.org/web/20020405175011/http://www.mindview.net/Etc/Discussions/CheckedExceptions |archive-date=5 April 2002 |url-status=dead }}</ref> which silently swallows exceptions, rather than letting the exceptions propagate to a higher-level exception-handling routine. In some cases, however, [[exception chaining]] can be applied instead, by re-throwing the exception in a wrapper exception. For example, if an object is changed to access a database instead of a file, an {{Javadoc:SE|java/sql|SQLException}} could be caught and re-thrown as an {{Javadoc:SE|java/io|IOException}}, since the caller may not need to know the inner workings of the object. However, not all programmers agree with this stance. James Gosling and others maintain that checked exceptions are useful, and misusing them has caused the problems. Silently catching exceptions is possible, yes, but it must be stated explicitly what to do with the exception, versus unchecked exceptions that allow doing nothing by default. It can be ignored, but code must be written explicitly to ignore it.<ref>{{cite web |url=http://www.artima.com/intv/solid.html |title=Failure and Exceptions |publisher=Artima.com |date=22 September 2003 |access-date=18 August 2013}}</ref><ref>{{cite web |url=http://www.shaunabram.com/checked-exceptions-article/ |title=Checked Exceptions |publisher=Shaun Abram |access-date=18 August 2013}}</ref> ====Try-catch-finally==== There are also differences between the two languages in treating the {{code|try-finally}} statement. The {{mono|finally}} block is always executed, even if the {{mono|try}} block contains control-passing statements like {{mono|throw}} or {{mono|return}}. In Java, this may result in unexpected behavior, if the {{mono|try}} block is left by a {{mono|return}} statement with some value, and then the {{mono|finally}} block that is executed afterward is also left by a {{mono|return}} statement with a different value. C# resolves this problem by prohibiting any control-passing statements like {{mono|return}} or {{mono|break}} in the {{mono|finally}} block. A common reason for using {{code|try-finally}} blocks is to guard resource managing code, thus guaranteeing the release of precious resources in the finally block. C# features the {{mono|using}} statement as a syntactic shorthand for this common scenario, in which the {{code|Dispose()}} method of the object of the {{mono|using}} is always called. A rather subtle difference is the moment a [[stack trace]] is created when an exception is being thrown. In Java, the stack trace is created in the moment the exception is created. <syntaxhighlight lang=Java> class Foo { Exception up = new Exception(); int foo() throws Exception { throw up; } } </syntaxhighlight> The exception in the statement above will always contain the constructor's stack-trace – no matter how often foo is called. In C# on the other hand, the stack-trace is created the moment "throw" is executed. <syntaxhighlight lang="csharp"> class Foo { Exception e = new Exception(); int foo() { try { throw e; } catch (Exception e) { throw; } } } </syntaxhighlight> In the code above, the exception will contain the stack-trace of the first throw-line. When catching an exception, there are two options in case the exception should be rethrown: {{mono|throw}} will just rethrow the original exception with the original stack, while {{code|throw e}} would have created a new stack trace. ==== Finally blocks ==== Java allows flow of control to leave the {{mono|finally}} block of a {{mono|try}} statement, regardless of the way it was entered. This can cause another control flow statement (such as {{mono|return}}) to be terminated mid-execution. For example: <syntaxhighlight lang="java"> int foo() { try { return 0; } finally { return 1; } } </syntaxhighlight> In the above code, the {{mono|return}} statement within the {{mono|try}} block causes control to leave it, and thus {{mono|finally}} block is executed before the actual return happens. However, the {{mono|finally}} block itself also performs a return. Thus, the original return that caused it to be entered is not executed, and the above method returns 1 rather than 0. Informally speaking, it ''tries'' to return 0 but ''finally'' returns 1. C# does not allow any statements that allow control flow to leave the {{mono|finally}} block prematurely, except for {{mono|throw}}. In particular, {{mono|return}} is not allowed at all, {{mono|goto}} is not allowed if the target label is outside the {{mono|finally}} block, and {{mono|continue}} and {{mono|break}} are not allowed if the nearest enclosing loop is outside the {{mono|finally}} block.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)