草庐IT

谈谈Java与C#的区别

公子驾到了 2023-04-03 原文

先听一个故事:Java与C/C++/C#的历史渊源

1972年的某一天,一个被称为“上帝的编程语言”的工具就此诞生,它是基于B语言的改进,并被正式命名为C语言。凭借着自身的优秀特性(贴近硬件、运行极快、效率极高等),C语言一经诞生,就在全世界范围内风靡,广大程序员用它开发了许多系统级的软件,我们熟知的Windows系统便是其中之一。C语言固然强大,但它并不是编程语言发展的终点,它带给程序员最大的困扰恰恰是它所提供的的强大特性——指针。指针的强大体现在可以直接操作内存,但指针的问题也同样体现在此。C语言并没有提供一套成熟的越界检查工具,而由此引发的Bug往往在编译期是无法被发现的,这就意味着,程序员要花费相当大的精力来处理使用指针而引发的问题。

于是在1982年,C++诞生了。C++不但兼容C语言,还新增了面向对象等许多特性,可以说,C++是C语言走向完善的更近一步,它在图形领域的诸多应用无不彰显着它的成功。但更完善意味着更复杂,C语言已经让许多程序员感到焦头烂额,而C++的复杂特性更是让人望而却步。

在这种情况下,Java在1995年应运而生。Java秉持着“C++ --”的思想,它保留了C/C++的许多内容(如面向对象特性等),以相似的语法减轻了C/C++程序员的上手难度;它摒弃了C/C++中令人又爱又恨的指针与内存管理,并以引用取而代之;它提供了真正的可移植性,所有以Java编写的应用都可以在JVM中运行;它提供了高质量的类库,大大方便了程序员的工作……

Sun公司推出的Java以其强大特性获得了Oracle和IBM等公司的全力支持,就连Sun的老对手——微软的创始人比尔盖茨也称其为“迄今为止设计最好的语言”。于是Java迎来了飞速发展的时期,并以惊人的速度快速占领了Web开发、服务器、Android手机端等各大领域。Java语言的设计虽然得到了比尔盖茨的肯定,但Java对市场的快速占领也让把持着C/C++帝国的微软感到忧心,他们急切需要一种新的、相似的语言,用以与Java分庭抗礼。正因如此,2000年,由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言——C#诞生了。

说了这么多,终于引出了本文的两大主角——Java和C#,那么下面我们就言归正传,来谈谈Java和C#的区别。

Java与C#对比

可以说,Java与C#的诞生都与C/C++存在渊源,因此两种语言既有相同,又存差异,我将从功能、语法、其它三方面来比较二者的异同。

功能方面

  • Java与C#都是面向对象的语言,都实现了面向对象中封装、继承、多态的思想。Java更多地借鉴了C++的优点,摒弃了C++不容易掌握的部分(如指针),并添加了一些新的特性;C#更多地借鉴了Java的优点,并添加了一些新的特性。
  • Java完全摒弃了指针的使用,而C#在非安全模式下支持指针,但大部分情况还是使用引用取代指针。
  • Java保留了C++的大部分基本数据类型,但没有保留结构体(struct);C#虽然保留了struct,但它大部分时候并不使用指针,因此容易引发复制性能问题。
  • java提供了代理模式,代理模式分为静态代理和动态代理,用于给对象提供一个代理,由代理控制对真实对象的访问,代理对象可以扩展真实对象,Java中使用Proxy类实现了动态代理,Spring的核心特性AOP的基础也是动态代理;C#提供了委托,委托用于实现事件和回调方法,使用delegate关键字定义。Java中可以使用代理实现C#中的委托功能,但相比于C#中的委托类型,显然要麻烦许多;C#中要想实现AOP,会很复杂,而Java只需使用动态代理即可。
  • Java和C#都有反射的特性,Java中通过Class对象获取类中信息,而C#中通过Type对象获取类中信息,二者所依据的对象类型不同。
  • Java各大框架的核心特性之一——注解(@Annotation),在C#中也有类似的实现,即Attribute,二者都是通过反射实现的。
  • Java的泛型是依托JVM实现的,Java代码在运行时会抹除了所有泛型信息(类型擦除),所以Java的泛型本质上都是Object对象,那些复杂冗余的类型转换操作由JVM代为完成了,从这个层面来看,Java的泛型实际上是伪泛型;C#的泛型是真正落实到CLR上的,CLR会为不同的泛型类型生成不同的具体类型代码。
  • 匿名内部类是Java独有的特性,它与lambda表达式相似,但又不同。lambda表达式只能实现函数式接口,而匿名内部类必须实现接口内的所有方法。当有些类只需要用一次时,可以使用匿名内部类对其定义并实例化,这在开发中是非常有效且简便的一种用法。

语法方面

  • Java中以package(包)管理“.java”文件,以import关键字引用其它包中的代码;C#中以namespace(命名空间)管理“.cs”文件,以using关键字引用其它命名空间中的代码。
  • Java和C#中都定义了public、private、protected、internal访问修饰符,但C#在此基础上还多出一个protected internal。
  • Java中实体类需要定义get()和set()来限制类中字段的访问权限,而C#中既可以以get()和set()来限制类中字段的访问权限,也可以以get和set访问器来限制类中字段的访问权限。
  • Java中使用extends关键字实现类的继承,使用implements关键字实现接口继承,而C#中统一使用“:”实现类和接口的继承;Java使用super()调用父类的构造方法,而C#使用base关键字。
  • Java中子类重写父类方法即可实现多态,而C#中必须以override关键字显示声明。此外,C#多提供了一种虚方法来实现多态。
  • Java和C#都是从main函数开始执行代码。其中,Java的main函数只有一种写法,Sting数组参数,无返回值,且m小写;C#中Main函数有四种写法,可带String数组参数也可不带参数,可以无返回值也可以返回int,且M大写。
  • Java使用system.out.println()输出,使用Scanner对象输入;C#使用Console.WriteLine()输出,使用Console.ReadLine()输入。
  • Java与C#都实现了for、while、do while循环结构。此外,Java中使用增强的for循环实现了集合的遍历,而C#中使用foreach循环。
  • Java与C#都实现了if-else和switch条件分支结构,但Java的switch只能处理整数,而C#的switch既可以处理整数,也可以处理字符变量;Java的switch可以不加break,而C#每个case后都必须以break结尾,否则将循序执行直至遇到以break结尾的case。
  • Java与C#的数据类型差不多,但C#拥有比Java更多的简单数据类型。此外,Java中字符串类型需定义为String类型,而C#中既可以用String类来定义字符串,也可以通过string关键字进行定义;Java中布尔型使用boolean定义,而C#中使用bool定义。
  • Java中只有值传递,而C#中既有值传递,也可以通过ref和out关键字实现引用传递。
  • Java和C#中都有改变循环次序的break和continue关键字,但Java摒弃了可能破坏程序结构的Goto关键字,而C#仍然保留。
  • Java不提供常量声明,但我们可以在类中通过private static final修饰变量,使其静态不可变,从而实现常量的作用;C#中使用const关键字声明常量。
  • Java中使用instanceof来判断对象的实例是否属于特定类型,而C#中以is关键字实现相同功能。
  • Java中的类型转换分为向上转型和向下转型,向上转型是指父类引用指向子类对象,可以自动实现转换,向下转型是指子类对象指向父类引用,需要进行强制类型转换;C#中提供as关键字实现对象类型的安全转换。
  • Java和C#中都有“//”单行注释,“/ * * /”多行注释,但Java中以“/ ** * /”定义文档注释,C#以“///”定义文档注释。

其它方面

  • Java编程主要使用IntelIJ IDEA,C#编程主要是用Visual Studio。从编译器的功能上来看,我愿称IDEA为世界上最好的编译器,没有之一。
  • Java以Maven管理项目,不仅提供了完整的生命周期,还包揽了Java项目环境配置、依赖管理等诸多复杂工作,为程序员的开发工作提供了极大的便利;C#以NuGet工具管理类库的安装,但似乎并没有提供类似Maven的专业项目管理工具。

参考文献

本博客参考如下链接,并结合自己的理解所写,如有不当,请予指正。

  1. 刘欣.码农翻身[J].中国信息化,2019(03):93.
  2. https://zhuanlan.zhihu.com/p/25106669
  3. https://www.php.cn/csharp-article-453533.html
  4. https://blog.csdn.net/lvshihua/article/details/8596048

有关谈谈Java与C#的区别的更多相关文章

  1. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  2. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  3. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  10. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

随机推荐