关于爪哇岛的常见误解和迷思
开发人员中存在很多错误的观点——有些源于误解、知识匮乏或过去的糟糕经验。Java 开发人员通常能够及时了解最新变化,但我经常听到非 Java 开发人员和整个 IT 行业人士这样说:
- Java 速度慢
- Java存在漏洞/不安全
- Java 不是免费的,所以你需要向 Oracle 支付很多钱购买许可证。
- Java 是一种冗长、过时的语言,其 API 使用起来也很麻烦。
我知道任何信息如果没有合适的背景都可能被误解,所以我尽量把它们串联起来,让它们说得通顺易懂。
Java 运行速度慢吗?
简而言之:否。
我记得大学的时候,我尝试过参加算法竞赛。它主要考察算法和数据结构,你需要编写代码来解决一些问题。验证是在远程服务器上进行的,服务器会根据输入的数据集测试你的解决方案。当时我只会Java,而服务器支持对Java编写的解决方案进行评估。用C语言编程的人最讨厌Java解决方案的地方在于,Java解决方案的执行时间明显更长,所以Java的运行时间限制不得不增加。
快进到2020年,Java已成为世界上最流行的编程语言之一,基于JVM的解决方案在数据密集型计算领域占据主导地位。Apache Kafka,作为领先的高速流处理平台之一,也运行在JVM上。这一事实本身就足以驳斥Java速度慢的说法。
然而,就性能而言,很少有东西能超越编译后的代码。但这就像比较苹果和橘子一样,因为Java字节码运行在JVM上——这赋予了它一个主要优势:可移植性。C代码一旦针对特定平台编译,就只能在该平台上运行。但Java编译后的字节码几乎可以在任何平台上运行。
另外,自 JVM 诞生以来,它不断发展,并且出现了许多专注于提高吞吐量和降低延迟的实现,例如GraalVM。
速度慢通常是由于之前使用过编写糟糕、过时的应用程序(例如用 Swing 编写的 GUI 应用程序)造成的。遗憾的是,Java 赋予了应用程序很大的自由度,因此即使某些功能能够运行,也未必能达到良好的性能。我认为StackOverflow 上的这个回答总结得最好。
*顺便说一下,速度慢是因为需要启动 JVM 才能运行代码。
Java是否存在漏洞或安全性问题?
简而言之:否。
同样,基于 Java 的解决方案有很多成熟的案例,尤其注重安全性,例如支付处理、数字签名、嵌入式设备(ATM)等等。Java 对加密、身份验证和授权、SSL 等都有广泛的支持,因此它能为你构建安全的应用程序提供必要的工具。然而,任何代码库都可能出现 bug,JDK 也不例外。幸运的是,频繁的更新可以修复这些关键问题。
除了应用程序代码本身之外,用户感知到的“bug”主要来源可能是机器上的 Java 运行时环境 (JRE) 版本过低。如果问题发生在服务器上运行的应用程序,那就是基础设施维护人员没有及时更新 JRE 的责任。用户也一样。你还记得那些烦人的弹出窗口吗?它们会告诉你 Java 有新版本。你还记得当时你是不是把它们关掉然后忽略了?其实,你刚刚就让你的电脑变得容易受到攻击。
问题可能出在您电脑上需要维护的额外组件(JRE)上,但现在大多数Java应用程序都已捆绑了JRE,用户无需单独安装。这在一定程度上降低了问题的可能性。
Java是免费的吗?
简答:是的。
这种困惑从何而来?2019 年,Oracle 宣布更改许可模式,如果您在生产环境中使用 Oracle Java,则需要购买订阅。这意味着,要么您拥有运行 Java 的服务器端应用程序,要么您拥有捆绑了 JRE 的桌面应用程序。拥有 Oracle Java SE 订阅将使您能够获得扩展支持。
也就是说,如果您不需要这种高级支持,您可以选择退出并切换到OpenJDK或其他供应商。有很多稳定且开源的 JDK 实现,它们通常能提供与 Oracle JDK 相同的体验。因此,答案也是肯定的,因为您可以选择不同的供应商。
Java 是一种冗长、只写且已过时的语言。
简而言之:否。
Java 有着悠久的历史,早期版本确实缺少一些结构,但任何语言都在不断发展和改进。让我们来看一段用 Java 7 编写的代码:
private static void java7() {
List<Person> persons = new ArrayList<>();
persons.add(new Person("Luke Warm", 10));
persons.add(new Person("John New", 15));
persons.add(new Person("Elsa Snow", 19));
persons.add(new Person("Mary Rose", 25));
Map<Maturity, List<Person>> adultAndChildrenMap = new HashMap<>();
for (Person person : persons) {
if (person.age >= 18) {
if (adultAndChildrenMap.containsKey(Maturity.ADULT)) {
adultAndChildrenMap.get(Maturity.ADULT).add(person);
} else {
List<Person> adults = new ArrayList<>();
adults.add(person);
adultAndChildrenMap.put(Maturity.ADULT, adults);
}
} else {
if (adultAndChildrenMap.containsKey(Maturity.CHILD)) {
adultAndChildrenMap.get(Maturity.CHILD).add(person);
} else {
List<Person> children = new ArrayList<>();
children.add(person);
adultAndChildrenMap.put(Maturity.CHILD, children);
}
}
}
System.out.println(adultAndChildrenMap);
}
这段代码过长且难以阅读。自 Java 7 以来,Java 已经有了许多改进,因此上面的代码现在可以写成:
private static void java11() {
var persons = List.of(
new Person("Luke Warm", 10),
new Person("John New", 15),
new Person("Elsa Snow", 19),
new Person("Mary Rose", 25)
);
var adultAndChildrenMap = persons.stream()
.collect(Collectors.groupingBy(
person -> person.age >= 18 ? Maturity.ADULT : Maturity.CHILD
));
System.out.println(adultAndChildrenMap);
}
目前的 Java 发布周期为6 个月,虽然 11 版本是 LTS(长期支持版),但当前版本是 14,它带来了更多改进,包括预览版和稳定版功能。Java 的问题在于它继承了大量的“遗留代码”,需要进行维护(例如Java 8 中引入的接口默认方法)。
自 2013 年发布的 Java 8(Java 最显著的一次更新)以来,Java进行了多次更新,旨在减少代码冗余并提高可读性,其中包括:
- 改进了 Collection API 的工厂方法(
Map.of(),,Set.of()等等) - Stream API 改进(
takeWhile/dropWhile) - 局部变量类型推断(
var list = new ArrayList<String>();) - 改进的
String效用函数(repeat(),,,isBlank()等indent()) -
多行
String:String html = """ <html> <body> <p>Hello, world</p> </body> </html> """; -
int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; }; -
if (obj instanceof String s) { // can use s here without explicit casting } else { // can't use s here } -
记录:
record Point(int x, int y) { }
任何语言都一样,要想有效使用,你需要学习所有的语法结构。对某些人来说,第一个用 Java 7 编写的代码示例可能比第二个更易读,但这仅仅是因为他们还没有掌握新的代码编写方式。
结论
这些话题都有很多可以补充的内容,值得一提的是,有时情况并非非黑即白(尤其是在性能方面)。我也知道,类似的错误说法也存在于其他语言中(比如Python速度慢、C#/.Net抄袭Java,或者JavaScript是外星人发明的,他们等着我们用它编写应用程序时发疯,然后占领地球)。
希望您喜欢这篇文章,欢迎在评论区分享您最喜欢的关于 Java 或其他语言的误解!
文章来源:https://dev.to/rapasoft/common-java-myths-and-misconceptions-3knk