从C#转向Java

39

我已经使用C#和更一般的.NET框架工作了几年。我经常听到C#和Java语言之间的相似之处,希望学习更多关于第二种语言。

  • 您有什么具体的建议来学习Java,当从C#转换时?
  • 一个C#程序员在开始使用Java时可能犯的任何常见错误?
  • 有没有文档展示可以保留的习惯和必须改变的习惯(仍然是从C#到Java的角度,因此需要比C# vs Java更具体的内容)?
10个回答

79

嗯,虽然 C# 和 Java 表面上很相似,但有许多小差异可能会让你感到困扰。一般来说,我认为相反的方向——从 Java 转向 C#——不太会有问题。这主要是因为 C# 是一种更复杂的语言,因此你可能会发现许多常见的 Java 模式变得简单了,但反过来可能会有些痛苦。

需要注意的事项(部分列表,不保证详尽):

  • Different ...

    • Naming conventions. In Java only type names start with a capital letter (i. e. PascalCase), everything else uses camelCase. Not very hard to adhere to, though.

      Also interfaces generally don't start with I. On the other hand you have to implement them with a different keyword. Doesn't really help in the middle of the code, though.

    • Class library :-)

      While obvious, this has been the thing I spent most time on when learning a language. When dealing with a known paradigm the syntax differences are quickly sorted out, but getting to know the standard library / class library / framework takes some time in some cases :-)

    • Patterns. Well, not quite, it's still the same stuff. But C# supports some patterns at the language level, while you still have to implement them yourself in Java. No events, but the Observer pattern (very prevalent in Swing—whenever you see a Listener, you know what to do :-))
    • Exception handling. Java has so-called checked exceptions which means that an exception must either be caught or declared upwards. Usually this means that you have

      catch (SomeException ex) {
        ex.printStackTrace();
      }
      

      pretty often in your code1 :-)

    • Types. While .NET has normal objects and value types, they both are objects and support methods, properties, &c. Java has a dichotomy of primitive types, such as int, float, char, &c. and classes such as String. Doesn't matter much since they implemented auto-boxing, but sometimes it's still annoying to wrap int in Integer.
    • Polymorphism: All Java methods are virtual by default whereas c# methods are not.
  • Minor syntactic differences.
    • foreach (a in b)for (a : b)
    • Different access keywords. Things like internal and protected internal don't exist. But unqualified members are visible to other classes in the same package (sort of internal, but then again not quite).
    • String comparison isn't done with == in Java. You have to use .equals(). While in C# == on strings is value equality, in Java == is always reference equality.
  • No ...

    • Properties. In Java this is generally done with the Foo getFoo()/void setFoo(Foo foo) pattern which C# generates silently behind your back when using properties but you have to do it explicitly in Java. Generally, to keep the language itself simpler many things in Java are just conventions. Still, most of the time you're better off adhering to them :-)
    • Operator overloading. Deemed a hazard to the righteous programmer they weren't implemented for fear of abuse. Don't need them too often anyway, not even in C#, but sometimes they are nice and then you're missing something.
    • Indexers. You always have to access list items through myList.get(5) instead of the array-like syntax myList[5]. Just a mild inconvenience, though.
    • LINQ (though there exist implementations2 but it's not as nicely integrated), or lambda functions3 (no delegates anyway, but anonymous classes), extension methods, or partial classes (yes, that's a painful one when dealing with Swing, unless you're very disciplined), and a few more things.
    • Multidimensional arrays. You can use jagged arrays (arrays of arrays), buttrue multidimensionality isn't there.
  • Generics are compile-time only, at runtime only Objects remain. Also wildcards in generics can be hard to resolve sometimes when the compiler complains about all of the four ? in your generics having different types. (Though to be fair: That was a case where I would have needed type information at runtime anyway so I reverted back to Objects).

一般建议:找一个有Java经验的朋友,让他浏览你的代码。虽然当你直接问他时他可能不能告诉你应该注意哪些问题,但他可以很好地发现代码中的奇怪之处并通知你。这对我学习Java非常有帮助(尽管我是先学了Java再学C#,所以可能会有所不同)。


1 是的,我知道很多catch块看起来不同,但是,这可能是原型之一,甚至并不罕见
2 Quaere, JaQue, JaQu, Querydsl
3 不过有lambdaj。感谢指出这一点,Esko


1
@Johannes Rössel:虽然Java中没有“真正”的lambda函数,但有LambdaJ:http://code.google.com/p/lambdaj/。 - Esko
6
@Ed:在C#中,“==”仍然被重载为值相等。当然,如果两个操作数中没有一个是字符串,则无法使用该运算符。然而,将字符串变量与字面字符串进行比较不应该有任何意外情况发生。 - Joey
继承和/或接口实现方面也有差异吗(是什么或有多少)? - Jay
@Ed:你说得对。这是一个陷阱,我同意。我认为Eric Lippert也写过一篇关于这个的博客文章。不过,编译器会发出警告,所以我认为虽然它可能有害,但在实践中不应该引起太多烦恼。 - Joey
@Jay:所有方法默认都是虚拟的,正如Florian Doyon在下面指出的那样:https://dev59.com/b3I95IYBdhLWcg3w3yJU#2110211 - 我错过了这个。 - Joey
显示剩余6条评论

15

我认为许多C#开发者学习Java最大的障碍其实是要学习新的集成开发环境(IDE)。Visual Studio非常优秀,当你长时间使用C#进行编码时,你已经习惯了它。但是,当你需要转向使用Eclipse或Netbeans时,你会突然感到迷茫。如何设置断点?即时窗口在哪里?如何创建Windows应用程序等等...我知道这听起来很疯狂,但我告诉你,人们会非常依赖他们的IDE,并且难以适应新的IDE。


1
同样的情况也适用于另一个方向:-)。尽管Eclipse的人们通常抱怨VS中的重构不好:-)。 - Joey
我觉得在Eclipse/VS之间切换并使用多种语言(如C++、C#、Java、Flex等)并不困难。 - Mr. Boy
@John:不,这并不难做,只是一开始有点令人望而生畏。 - BFree
1
@Johannes。你可能已经知道了Resharper,但如果还没有,请查看一下。如果没有它,VS中的重构确实很糟糕。 :) - Russell Troywest
@mrp:我用过它,但价格有点贵,对于我目前在使用VS做的一点小事情来说,我不愿意承担这个成本。在工作中我们也没有使用它。目前我回到了Eclipse(用于Java)和文本编辑器(用于其他所有内容);-)。我发现Resharper在建议修复代码方面有点过于热情,虽然我并不想仅仅因为能够而将每个委托重写为lambda表达式。 - Joey
不仅仅是集成开发环境(IDE),还涉及Java的整个开发环境。我从未遇到过一个新的C#项目模板一开始就可以顺利运行的情况,所以感觉很宠坏了而且有些迷失…… - Sinaesthetic

10

这些编程语言本身非常相似,除了一些关键字和 C# 程序员已经习惯的特性(如属性、using 和具有实体化泛型的能力)在 Java 中缺失。

主要问题在于对框架的了解,Java 框架数量有数千个。


4
感谢您提到框架。Java语言相当简洁(有多少关键字?),但您可能需要学习的框架很大,有时会很繁琐,例如J2EE。 - blank

5

主要语言没问题。了解库将是需要花费时间去做的一件事情。如果你正在做网络应用程序,有很多东西需要学习...相当于WCF和ASP.net的技术。 你没有说你所在的领域是桌面、服务器还是Web服务器?


2
这正是我想说的。作为一名学习C#的Java程序员,语言很容易(而且大部分相同),难的是导航和学习库,同时还要适应不同的IDE。 - Tom Neyland

3

C#和Java之间最大的区别是:在Java中,所有方法都是virtual。这也是为什么像NUnit这样的工具来自于Java世界的原因。


我冒昧修改了社区维基。 - Florian Doyon

2

1

你需要学习的最重要的事情是如何在Java中使用Greenspun C#的函数式编程特性。例如,你可以期望创建许多只有一个方法的接口来解决Java缺乏lambda函数和委托的问题。


我认为这是我最害怕的 D: - Sinaesthetic

1

我真诚地推荐Java in a Nutshell。大多数Java/任何其他语言的入门书籍都是为完全新手读者编写的,解释循环概念需要几页,递归则需要一章……你可以在两天内开始使用这本书编写Java程序。当然,理解底层发生了什么以及如何使用所有可用框架需要很长时间。但是一旦掌握了语言本身,即使只使用谷歌资源,也很容易上手。


1
我曾经从Java转向C#,然后又回到了Java。我认为它们在语法上非常相似,我遇到的大部分问题是学习.NET API以及学习如何有效地使用它们。很多时候我都在使用“语法糖”,将我的代码写成Java风格,然后将其翻译成C#。我花了很多时间在微软网站上阅读和学习API,这对我帮助很大。

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接