首页 > 代码库 > C#和Java之比较(语法篇)
C#和Java之比较(语法篇)
C#和Java作为独立发展的两种程序设计语言,其实有很多相似的地方;当然,其中还是有一些不同的点的;假如一个熟悉C#但不清楚java的程序员去写java程序,其实没有多大困难,只是如果清楚了C#和Java中的一些不同的点,应该可以更快的从C#过渡到Java的。
本文主要是列举了笔者在学习Java过程中和C#比较的一些异同。希望可以给同样从C#转向Java的开发人员提供一些信息。
IBM的开发者网站提供了一个不错的java入门系列,对于初学者来说不妨一看。
https://www.ibm.com/developerworks/cn/java/intro-to-java-course/index.html
另外wiki中其实也已经有一些详实的对于java和C#的比较,可以参看
https://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java
Namespace(C#) vs Package(java)
C#和java都是面向对象的编程语言;在源代码的层面,C#的组织结构是命名空间=>类=>方法/变量/常量,而Java稍有不同,用package代替了C#中的namespace,但是所起的作用是类似的。
同样的,当一个namespace或者package中需要用到其他的命名空间下的类时, C#通过using指定上下文可以访问的namespace,而Java通过import导入package来达到同样的目的。
代码示例
Java
package hello.world; import java.lang.*; public class HelloWorld { private static final int CONSTINT = 100; private String variable; public void method(){} public static void main(String[] args) { System.out.println("Hello World!"); } }
C#
using System; namespace Hello.World { public class HelloWorld { private const int CONSTINT = 100; private string variable; public void Mehtod() { } static void Main(string[] args) { System.Console.WriteLine("Hello World!"); } } }
访问限定修饰符
C#和Java中,对类型、方法、变量等都可以指定访问限制修饰,来达到封装、继承等等目的。
Java中的访问限定修饰符的各个访问限定如下,这个包就是package
public | 可由任何类调用 |
protected | 仅能由同一个包中的类或任何子类调用 |
无修饰符 | 由同一个包内的任何类调用 |
private | 仅能由定义它的类调用 |
C#中的访问限定描述如下,这个里面有一个程序集assembly的概念,和namespace不太一样。
public | 可由任何类调用 |
protected | 仅可以被所定义的类型或者其嵌套类型或者其派生类型调用 |
internal | 仅可以被程序集中的类访问 |
protected internal | 仅可以被所定义类型、派生类型以及任何定义在同一程序集中的类访问 |
private | 仅能由定义它的类调用 |
无修饰符 | 同internal修饰符 |
属性
C#有Property的概念,通过简单的get/set就可以定义public属性;C#中的属性本质上就是两个方法,一个setter,一个getter, 只是C#在语言层面提供了友好的支持。
Java就没有这种语言层面的支持,如果想实现同样的功能,必须首先定义变量,然后定义一个Set方法,一个get方法;当然现在很多IDE插件可以帮助做第二步自动生成这两个方法。
示例如下
C#
namespace Hello.World { public class Person { public int Age { get; set; } } }
Java
package hello.world; public class Person { private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Foreach
带有迭代器的类型,都可以使用foreach语法来比较优雅的替换for循环。Java和C#的语法略有不同。
代码示例如下
C#
namespace Hello.World { public class HelloWorld { static void Main(string[] args) { foreach (var str in args) { System.Console.WriteLine("Hello World!" + str); } } } }
Java
package hello.world; public class HelloWorld { public static void main(String[] args) { for(String str : args){ System.out.println("Hello World!" + str); } } }
这里顺便提一下的是,Java中没有类似C#中万能类型var这种定义方式了,所有变量必须要显示的写清楚定义类型,这个可能会给写惯了C#的同学带来点不适应。
集合
相比于C#, Java内置的集合功能稍显薄弱,在使用便捷上不如C#。
Java中只有基本的数组类型支持原语类型(int/long/boolean/char etc), 而其他的集合比如List,Map等只能包含对象类型。而在C#中,所有集合都可以同时支持值类型和引用类型。
C#中,对集合中的元素操作可以使用lamda表达式以及linq的方式,对集合中的每个元素进行操作,选择,过滤,转换等等,非常方便。而在Java中,直到java 1.8之后,才支持在集合类型后面,借助类似lamda表达式的方式访问操作集合中的每个元素,并且内置的功能方法非常少。
一些代码示例如下,可以看到,使用C#代码精简不少,并且有不少内置方法可用(如下代码不考虑性能开销,只是纯粹展示一下C#中对集合操作的各种可能性)。
C#
using System.Collections.Generic; using System.Linq; namespace Hello.World { public class HelloWorld { static void Main(string[] args) { var persons = new List<Person>(); persons.Add(new Person() { Age = 21 }); persons.Add(new Person() { Age = 19 }); persons.Where(p => p.Age > 20).Select(p => p.Age).ToList().ForEach(p => System.Console.WriteLine("Age-{0}", p)); } } }
Java
package hello.world; import java.util.ArrayList; import java.util.List; public class HelloWorld { public static void main(String[] args) { List<Person> persons = new ArrayList<Person>(); Person p1 = new Person(); p1.setAge(21); persons.add(p1); Person p2 = new Person(); p2.setAge(19); persons.add(p2); persons.forEach(p -> { if (p.getAge() > 20) { System.out.println(String.format("Age-%s", p.getAge())); } }); } }
继承和多态
C#和Java都很好的支持面向对象编程,只是在具体编码上稍微有些不一样。
主要在两点,子类构造的时候对父类的构造;重写。
构造的传值这块,C#把调用父类的构造方法移出到函数外面调用,以示区别,个人觉得这个比较人性化。
重写这里,Java父类中的任何方法都可以被重写,只要加上@Override的注解;而C#中需要在父类可能被重写的方法加上virtual关键字,后续子类重写时,在使用关键字override;感觉C#更加严谨一些。
另外,C#和Java中限定一个类不能被继承的关键字也不一样,C#使用sealed,Java是final。
代码示例如下
C#
namespace Hello.World { public class Person { public virtual void doAction() { System.Console.WriteLine("Person"); } } public class Employee : Person { public Employee() : base() { } public override void doAction() { System.Console.WriteLine("Employee"); } } } namespace Hello.World { public class HelloWorld { static void Main(string[] args) { Person p = new Employee(); p.doAction(); } } }
Java
package hello.world; public class Person { public void doAction(){ System.out.println("Person"); } } public class Employee extends Person{ public Employee(){ super(); } @Override public void doAction(){ System.out.println("Employee"); } } public class HelloWorld { public static void main(String[] args) { Person p = new Employee(); p.doAction(); } }
C#和Java之比较(语法篇)