在1996年至2002年之间,我用Java编写了成千上万行代码。我用Java 1.0到Java 1.4编写了Web框架,电子表格以及更多内容。

与90年代中期(预模板)的C ++相比,Java是一种完全令人惊奇的语言。 JVM是所有计算机语言的最佳运行时。

漫长的奇特之旅

从2002年开始,我开始做C#。 然后是露比 然后是Scala。 一些Haskell,最近,我做了很多Clojure。

因此,我今年完成的Java 1.5 / Generics数量非常有限。

有一个Java演出

今年,我参加了一场演出,编写了一些非常有趣的代码(编写了一个编译器)。 但是,客户是一家Java商店。 该项目已经具有Java基础。 客户坚决认为该项目全部用Java来完成……不是Scala……不是Clojure……不是JRuby,而是Java。

因此,在过去的6个月中,我花了数千行Java代码。 我已经了解了Java在过去10年中的发展情况,这令人震惊。 令人震惊的Java变得多么糟糕。

基本上,Java毫无意义。 据我所知,泛型将给定程序的总字符数增加约20%-30%。 尽管Scala的类型(带有类型推断)与Ruby相比是纯正的(在我看来,陪审团无法确定Scala的类型系统的重量与其相对于类型较少的Clojure的价值)。我可以认为泛型不值得在类型检查与Java 1.4的边际改进之间进行。

因此,我将介绍我认为可以使Java更好而又不会破坏语言的东西。

这不是“ Scala更好的帖子”

请注意,该帖子不是“ Scala更好”的帖子。 尽管帖子中的某些想法来自Scala,但我认为Scala(或Clojure)不能替代Java。 Scala只是一种语言,我已经看到大量的Scala滥用。

此外,我认为Scala在很大程度上已经遭受了Java所遭受的同样的痛苦(增加了语言的权重和复杂性(主要是通过Scala的类型系统)来解决边际问题),考虑到两种语言,这不足为奇的血统。

有些东西可能是在JDK 8中提出或提出的

这些是我的想法。 我不是JCP地区的球员。 感谢与Sam Pullara的出色午餐,我了解Java 8中的lambda。 但是我没有处理太多的JCP通信,因此JCP提案可能涵盖了这些想法。

默认公开

除非有明确的可见性级别,否则将所有声明默认为public 。 是的,我知道这会破坏现有的一些代码,但是让我们将默认值设置为正确的值即可。

为什么? 由于我们的代码中包含的噪声越少,信号越突出。

最后一个表达式是返回值

信号变得更有价值的另一个地方不再需要return关键字。 最后一个表达式成为返回值:

int plusOne(int x) {x + 1;}

仅当方法中没有return语句时才适用。 因此,如果您打算将return用于控制流编程,则必须明确。 但是对于小的,简单的方法,摆脱return意味着更少的视觉噪音。

块表达式

花括号中的任何内容都是一个块表达式,而不是一个块语句。 这意味着如果花括号内容可以是一个表达式,则将其视为此类。

String s = {var d = new Date();"The current date is "+d;
}

某种类型推断

我想看到自动分配推论。 基本上:

var name = "David"; // it's a String, duh

我们不需要使var为关键字。 基本上,类型var成为“推断类型”类型。

和基本的左侧参数类型推断(请注意,IntelliJ已经使用此语法):

List<String> stuff = new ArrayList<~>();

如果返回值只有一条路径(除了方法的最后一行,没有return语句),则返回类型推断:

plusOne(int x) // it's an int{x + 1;}

以上所有更改都可以使用编译器已知的数据来完成。 无需花哨的算法。 只是减少了程序中重复单词的数量……而通过泛型类型推断,无论如何,IDE都已经在IDE中显示了这些内容。

更好的平等测试

===添加为equals方法的别名,但要求===的右侧与右侧协变。

另外,将!==添加为!equals

具有元数据的简单,不可变的数据结构

用Java表示简单数据是一个巨大的痛苦。 是的,IDE在创建getter / setter方面大有帮助。 但是最终,我们的许多程序都包含原始数据。 因此,我建议向Java添加内部数据结构。

这些是Scala的案例类与Clojure的元数据工具的组合。

struct只能在顶级公共类中。

例如:

public class MyStuff {struct Name(firstName = "David", lastName = "Pollak", age = 49, Date birthday = null)public static boolean funWithNames() {var archer = Name("Archer").age(10);var tessa = Name().firstName("Tessa").lastName("kitten").age(1);assert(tessa.age === 1);assert(tessa.getAge() === 1);archer !== tessa;}public static void metaData() {var david = Name("David", "Pollak");Name d2 = david.setMeta("geek", "true");assert(david === d2); // metadata not part of equality testingassert(david != d2); // object instances not the sameassert(david.getMeta("geek") === null);assert(d2.getMeta("geek") === "true");}
}

你从struct得到什么?

  • 不可变对象的创建,无需使用每个参数的new且具有位置构造函数,以及简单的名义上的创建和新值链接。
  • 与每个struct相关联的元数据的Map<String, String>
  • 每个字段的默认值。 这允许添加字段,并且带有附加参数的库的新版本不会破坏访问旧版本的代码。
  • 一个toString方法,它输出字段名称和值。
  • 一个正确实现的equals方法,可以通过对空字段的适当处理来进行所有字段的比较。
  • 计算哈希码的hashCode方法(如果已知所有字段都是不可变的,则应将其缓存)。
  • 字段级访问器方法。
  • 每字段复印机: field(param)这允许创建具有新值的新实例。 元数据已复制。
  • 每个struct都有大量的元数据,包括字段名称列表,每个字段的类型。 该元数据可以用于快速,高效,自动生成的一组序列化器/反序列化器(例如JSON,JDBC,XML)。

另外,请注意定义的语法。 如果可以,则推断类型。

对于每个包含struct类,将有一个ClassName.struct接口。 该接口由所有struct实现,并且该接口包含所有共享字段。 例如:

class People {struct Parent(String name = null, List<People.struct> kids = null)struct Kid(String name = null, Parent parent = null)String getName(struct person) {person.name;}
}

注解也可以完成很多事情(例如,增强struct的JSON可序列struct等)

但是,通过轻量级的方法在语言级别定义数据模式,可以使代码更快地编写,更易于维护和更具可读性。

精铸

Java转换过于冗长且容易出错。 使用if / instanceof / cast模式需要大量代码,并且非常容易出错,因为该类被指定了两次……一次在测试中,一次在强制转换中。

我们可以从Scala借用我最喜欢的功能之一:模式匹配,但是只需执行以下操作:

String testIt(Object o) {switch o {String s: s;Number n: "It's a number: "+n;Date d if d.millis() > 0: {var formattedDate = formatDate(d);"It's a modern date: "+formattedDate;}default: "No clue";}
}

好吧...我们有什么? 该类已测试。 如果该类是匹配项,则将其分配给变量(仅具有行范围)。 接下来,运行警卫,看看是否应该采取这种行动。 如果是这样,请运行:右侧的表达式。

请注意,这种形式的切换是一种表达方式,而不是一条声明。 另外,请注意,不会掉线。

那么,这还能使事情变得更容易吗?

String whatSize(int i) {switch i {v if s < 10 : "small";v if s < 100 : "medium";default: "large";}
}

我们可以做的下一件事是将其应用于struct s(不,这不是模式匹配):

String aboutPerson(People.struct p) {switch p all {Parent p: "A parent named "+p.name+" #"+p.kids.size();Kid k: "A kid with "+(k.parent.kids.size() - 1)+" sibs";}
}

express后面的all关键字表示必须匹配。 如果将新struct添加到类中,这将很有用,因为所有在该struct上打开的位置都将标记一个编译时错误。

不变的收藏

Java迫切需要一个出色的不变集合包。

基本上,该软件包是Clojure出色的MapVector类的纯复制品。 我们不需要很多花哨的Scala风格的收藏。

实现java.util.Listjava.util.Map不可变集合。 基本上,这些集合将是独立的。

结合JDK 8 lambda,我将在Scala和Clojure的集合操作方面得到我的一大堆爱。

所以你有它

所以你有它。 我认为以上内容将使Java更易于处理语言。 它将减少冗长。 它将允许将数据作为相当常见的数据进行处理,尤其是在编写将数据编组进出系统的服务时。

上述更改将减少Java的冗长性,而不会显着降低Java的“讲述故事”代码。 而且,是的,有可能编写相当难以理解的Scala代码。 我们不想去Scala去的地方。

我还想看什么? 按名称调用参数(我不知道它们是否会成为lambda的一部分)。 属性。 看看是否有可能在Java中进行某种形式的全局类型推断也将很有趣。 但是所有这些东西都是另一天。

继续前进!

参考: Java: DPP博客博客中来自JCG合作伙伴 David Pollak 的本地最低语言标准 。

翻译自: https://www.javacodegeeks.com/2013/10/java-a-local-minimum-language-wise.html

Java:本地最小语言相关推荐

  1. java:8最小镜像_Java:本地最小语言

    java:8最小镜像 在1996年至2002年之间,我用Java编写了成千上万行代码.我用Java 1.0到Java 1.4编写了Web框架,电子表格以及更多内容. 与90年代中期(预模板)的C ++ ...

  2. Java与C语言中的锁

    Java与C语言中的锁 C 嵌入式汇编的语法格式是: asm(code : output operand list : input operand list : clobber list) __asm ...

  3. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  4. 【Groovy】Groovy 语言特点简介 ( 支持 Java 语法 | 支持 Java 虚拟机 | Groovy 语言是动态语言 | Groovy 扩展 JDK | 编译时元编程 )

    文章目录 一.Groovy 支持 Java 语法 二.Groovy 支持 Java 虚拟机 三.Groovy 语言是 动态语言 四.Groovy 扩展 JDK 五.Groovy 编译时元编程 一.Gr ...

  5. java swing调用H5_atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97...

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1.实现html5化界面的要解决的策略 1.1.Js交互 Firefox与Chro ...

  6. JAVA调用C语言程序

    JAVA调用C语言程序 JAVA调用C语言程序 1. 编写带有native声明的方法的Java类 2. 使用javah 生成:jniSample.h的头文件 3. 使用C实现本地sum方法:(这里我生 ...

  7. java和C语言在数据类型和语法上的比较

    一.数据类型 1.Java:Java的数据类型可分为两大类: ①基本数据类型:byte.short.int.long.double.float.boolean.char ②引用数据类型:类.接口.数组 ...

  8. Groovy – Java的脚本语言

    Groovy – Java的脚本语言 by Mark Volkmann, Partner Object Computing, Inc. (OCI) 翻译:raxy 介绍 Groovy是用Java实现的 ...

  9. Java回炉之语言基础

    Java回炉之语言基础 Java回炉之语言基础 DOS命令 java编译过程 path和classpath的区别 关键字表 数据类型 位运算 算数优先级 内存划分 类的初始化过程 static关键字特 ...

最新文章

  1. python安装要钱吗-python语言是免费还是收费的?
  2. C++文件类(文件流类)及用法详解
  3. VBS 自动打开软件
  4. 怎么解决python Non-ASCII character错误
  5. 0054-软件版本号问题
  6. Nacos系列:欢迎来到Nacos的世界!
  7. 《Android开发从零开始》课程下载地址汇总
  8. Oozie 调用sqoop导数据出现NoClassDefFoundError问题
  9. HDU 1074 Doing Homework 状态压缩 + 搜索
  10. [UVA 11374] Airport Express
  11. cad2020 开始_中望cad2020发布,附简体中文免费版安装教程
  12. 苹果设备解锁工具iToolab UnlockGo Mac
  13. 计算机属性资源管理器已停止工作,Win7资源管理器老是停止工作怎么办?资源管理器已停止工作解决方法...
  14. 思科cisco2800系列路由器
  15. 1KB文件夹快捷方式病毒解决方法
  16. PTA每日一题-Python-人民币与美元汇率兑换程序
  17. Bugku web——秋名山老司机
  18. Sigmod 和 Logit
  19. Generality
  20. android7.0模拟器pc版,安卓9.0模拟器电脑版

热门文章

  1. android roboguice2,Android快速开发框架 roboguice
  2. python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式
  3. sap wad_使用网真和WAD热部署Kubernetes
  4. 世界是沙粒还是宇宙_看到一个沙粒世界:再一次你好世界
  5. switch字符串jdk_JDK 12 Early Access Build 12中的原始字符串文字支持
  6. jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值
  7. drools 执行函数_Drools可执行模型还活着
  8. idea测试单元错误_不要单元测试错误
  9. 带有PostgreSQL的Docker Compose for Spring Boot应用程序
  10. TestNG中的参数化– DataProvider和TestNG XML(带有示例)