语法啰嗦——我为什么讨厌Java(2)

楔子

上回,我们引出了超级语言,并且介绍了超级语言的一些特性,讲超级语言与Java进行对比,我们今天讲的深一点,从深层的方面了解一下为什么我讨厌Java

语言先天劣势

泛型,真的有吗?

我们观察一下以下的Java代码:

int sampleInt = 5;
Integer sampleInteger = 5;
List<int> intList = List.newArrayList(); //Not allowed
List<Integer> integerList = Lists.newArrayList();

Java里使用泛型,所有的数据类型都必须使用包装好的类。这是常识,但有更深层的原因。

为了探究,我们对比一下超级语言的代码,为了方便,这里不使用隐式变量声明:

int sampleInt = 5;
Int32 sampleInt32 = 5;
List<int> intList = new List<int>();
List<Int32> int32List = new List<Int32>();
List<Int32> list = new List<int>(); //This is also allowed

没错,在超级语言中,intSystem.Int32是完全相同的东西,为了进一步了解,我们翻一下Int32的实现代码:

[Serializable]
[StructLayout(LayoutKind.Sequential)]
[TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]    
public readonly struct Int32 : IComparable, IConvertible, IFormattable, IComparable<int>, IEquatable<int>, ISpanFormattable
{
	private readonly int m_value; // Do not rename (binary serialization)
	//...
}

你会发现这里有一个套娃定义,但实际上这个定义只是定义了int的各种方法,将int视为了一个对象,仍然是Object的子类,因此你可以使用int.ToString。在超级语言里,所有的类型都是Object及其子类。

Java呢?没有这种关系,intInteger完全是两个东西,最直观地看,是上面泛型的问题。更简单地,没有运算符重载的Java比较Integer使用的是equals方法,而不是int那种==

Java这种繁琐的设置,其实是在这种情况下是较为合理的。之所以说其合理,是因为JVM不支持泛型,有类型擦除。对于JVM,一个List<Integer>List<String>是没有区别的,所有的泛型的T其实都是Object,只不过编译时的静态类型检查使这个过程变得安全。正是因为JVM的设计不足,使得Java只能使用这种繁琐的语法。

所以为什么Java在设计的时候,为什么不让编译器进行检查,将泛型处的int转化为Integer呢?个人看法是如果真这么做,那么不如一开始就使用与超级语言一样的设计,那样反而更加简便一点。

List怎么转换成数组啊???

然而,类型擦除带来的危害是毁灭性的。

在超级语言中,如果一个List<T>想转化为数组,很简单,一个内建的方法就可以实现:

var list = new List<int>();
int[] arr = list.ToArray();

当然,Java中也有toList的方法。

List<Integer> list = new ArrayList<>();
Object[] arr = list.toArray();

返回的是居然是Object[]?而且这个Object数组也无法强制转换回你想要的类型。

那么要想返回正常的呢Integer呢?

当然可以,你可以传参啊,传参了就有了啊,还有三种方式可以选择呢!

Integer[] arr = list.toArray(Integer[] ::new);
Integer[] arr = list.toArray(new Integer[0]);
Integer[] arr = list.toArray(new Integer[list.size()]);

这加上不传任何参数的裸toArray,简直就是茴香豆的茴的四种写法!

有一回对我说道,“你写过代码么?”我略略点一点头。他说,“写过代码,……我便考你一考。Java中的List转换成数组,怎样转的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。J乙己等了许久,很恳切的说道,“不能转罢?……我教给你,记着!这些方法应该记着。将来做Java程序员的时候,写代码要用。”我暗想我和Java程序员的等级还很远呢,而且我们写超级语言的也从不纠结List转数组的事情;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是直接调用一个toArray方法?”J乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说,“对呀对呀!不过你这样得到的是Object数组……List转数组有四样写法,你知道么?”

这API,怎么如此混乱?

我们先来看一下以下几个语言,在sample.txt中写入Hello!的一些实现。

FILE* file = fopen("sample.txt", "w");
fputs("Hello!", file);
fclose(file);
int file = open("sample.txt", O_WRONLY);
write(file, "Hello!", 6);
close(file);
auto stream = ofstream();
stream.open("sample.txt", ios::out);
stream << "Hello!";
stream.close();
await File.WriteAllTextAsync("sample.txt", "Hello!");
await using var stream = new StreamWriter("sample.txt");
await stream.WriteAsync("Hello!");
File file = new File();
FileWriter writer = new FileWriter(file);
writer.write("Hello!");
writer.close();

如果你用过C、C++,那么对于文件读写,你的第一印象一定是File或者Stream之类的。如果你之前没有学过编程语言,你的第一步肯定是往File里面想。如果你用的是Java,那么恭喜你,找到了一个File类,new了一个然后发现没有Write的方法。然后在网上搜索,需要一个FileWriter。如果你觉得这种级别的API还可以接受,那么感受一下下面的。

对于队列,C++进队是push,出队是pop,虽然有些奇怪但是人类是能理解的,因为栈也是pushpop;超级语言的进队是Enqueue,出队是Dequeue,这是个人类都能理解;而Java中居然是offerpull!在没有事先了解这个API或者当场查资料,是不会把进队与出队的指令往这两个单词上面去想。

对于字典,C++是insertatinsert可以理解,at有些晦涩但是C++可以通过[]来访问元素,所以这两个函数的存在感比较低,也没用必要纠结;超级语言则提供了AddTryAdd[]TryGet四种方式,有直接的,也有安全的,人类也能理解其含义;而Java,居然是惊天泣地洞鬼神的putgetget还好说,put简直莫名其妙,对于一个字典,put实属奇怪。

本段小结

很多人吹Java,都是吹Java第三方库多,轮子多。实际上,这正是Java语言特性缺失,API混乱,语言库简陋造成的原因。连十分重要的协程都需要第三方库来完成,真的是残废语言。

我为什么讨厌

说了这么多,只是列举了Java的缺点,好像并没有说明我为什么讨厌Java。实际上,使用麻烦就是我讨厌的地方。上一篇主要是从客观的角度说明Java的缺陷,而这一篇则是从主观的角度说明Java的各种不符合逻辑的地方,引起我的厌恶。对于我来说,第一个接触的编程语言是Pascal(虽然没怎么学好),第二个语言则是Visual Basic 6。虽然那是一个很古老的语言,但是其用起来方便,而且其对于字符串的比较是可以使用等号的。后来我发现VB还有新的版本,就下载了Visual Studio入了一个更大的坑,学习到了Visual Studio上的其他语言。直到今天,每次重装系统,我的电脑上一定会有的软件肯定有Visual Studio。后来首次接触Java是想做一个Android应用程序,可是我不会Java啊,就按照类似语法的语言往上套,然后踩进了字符串比较这个无尽深渊里。当时好像是一个侧菜单,ifelse来决定做什么,而上一个返回的是一个String,我就在那里if(str == "aaa)在那里做。然后发现每次都是false,一直没整出来,我就把AS给卸载了。是的,直接卸载了,然后再也没有碰这门语言,直到最近。后来才知道Java没有运算符重载,比较需要使用equals方法。也许我和Java注定不合适,从见面的那一刻起我们就不合适。之后我就成了一个Java坚定不移的黑子,直到现在。

这个系列还会有(3)吗,可能会吧。但是我确定的是,除了玩MC外,在这门课结束后,我的电脑再也不会有Java的身影了。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇