草庐IT

盘点 Java 十大语言设计问题

迷路的架构师 2023-04-02 原文

1.空指针异常(NullPointException)

Java 语言缺乏对空安全(null-safety)的内置支持,可能导致 NullPointerException 异常。这是所有Java开发的必须经历的痛苦。并且需要花大代价进行处理:使用Optional。

// 使用 ofNullable() 方法创建 Optional 对象
Optional<String> name = Optional.ofNullable(getName());
// 使用 map() 方法转换 Optional 对象的值,使用 orElse() 方法获取默认值
String message = name.map(n -> "Hello, " + n).orElse("Hello, Guest!");
System.out.println(message);

2.语法冗余

  1. 必须分号结束语句。
String str = "没有分号会报错";
  1. 必须明确的访问修饰符:类、方法和成员变量都需要明确指定访问修饰符(如 public、private、protected)。
public class MyClass {
private int x;
protected String y;

public MyClass() {
// ...
}

public void myMethod() {
// ...
}
}
  1. 重复的类型声明:在 Java 中,变量声明时需要明确指定类型,这会导致代码显得更冗长。Java 10 引入了局部变量类型推断(var 关键字),可以在某些情况下减少冗余。然而,这个特性并不适用于所有场景,例如类成员变量和方法参数。
List<String> names = new ArrayList<String>();
Map<String, Integer> map = new HashMap<String, Integer>();
  1. 冗长的异常处理:说真的,看到下面这样的结构想死的心都有了。
public void readFile(String filePath) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = reader.readLine()) != null) {
// do something with line
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

我们实际需要的代码只有一点点:

public void readFile(String filePath) {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = reader.readLine()) != null) {
// do something with line
}
}

3.缺少属性(Properties)支持

Java 没有内置的属性支持,开发者需要为类的成员变量创建 getter 和 setter 方法。

4.缺少内置的函数式编程支持(Java 8 之前)

Java 8 之前,Java 缺乏对函数式编程的内置支持。虽然 Java 8 引入了 lambda 表达式和 Stream API,但仍然不如一些其他编程语言(如 Scala、Haskell)对函数式编程的支持更为丰富。

List<String> list = Arrays.asList("apple", "banana", "orange", "pear", "watermelon");
list.stream() // 这里必须.stream()才能用,感觉非常别扭
.filter(s -> s.length() >= 5)
.forEach(System.out::println);

5.类型擦除(Type Erasure)

Java 泛型的实现是基于类型擦除的,在运行时泛型类型信息会丢失,限制了泛型代码的能力,导致无法创建泛型数组和泛型实例。

T obj = new T(); // 不支持
T[] array = new T[]; // 不支持

6.基本类型与包装类型

Java 中的基本类型(如 int、float、boolean)与对应的包装类型(如 Integer、Float、Boolean)存在差异,它们在使用时可能导致不一致的行为。自动装箱和拆箱可以在某种程度上解决这个问题,但仍然需要注意。

7.受检异常(Checked Exceptions)

Java 中有两种类型的异常:受检异常(如 IOException)和非受检异常(如 NullPointerException)。受检异常必须在方法签名中声明或者进行捕获处理,这会导致异常处理的代码显得更加繁琐。

看到下面的代码,表示一脸嫌弃。

public void add() throw Exception {
//
}

8.缺少对值类型的支持

Java 语言缺乏对值类型的支持,所有对象都是引用类型,容易导致性能问题。尽管 Java 的开发团队已经意识到这个问题,正在通过 Project Valhalla 探索解决方案,但目前 Java 语言仍然不支持值类型。

9.单继承限制

Java 语言只支持单继承,一个类只能继承一个父类。虽然可以通过接口实现某种程度的多继承,但仍然不如多继承灵活。

10.可变性与不可变性

Java 语言中的类和对象默认是可变的,这可能导致数据不一致和线程安全问题。虽然可以通过一些设计模式和实践来实现不可变性,但 Java 并没有内置支持。

有关盘点 Java 十大语言设计问题的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  7. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  8. 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/

  9. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  10. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

随机推荐