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!
=== 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}} |}
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)