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

java:8最小镜像

在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令人惊讶的冗长,视觉分散,丑陋的东西我可以想到泛型不值得在类型检查与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都已经显示了它们。

更好的平等测试

===添加为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 testing
    assert(david != d2); // object instances not the same
    assert(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:8最小镜像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值