Java 10大装B写法,看完可以出去吹一波了!

感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30600.html

Java 10大装B写法,看完可以出去吹一波了!

想不想学习装 B 式的 Java 骚操作花式写法?

没错,本文栈长来教你!

1、集合初始化

集合的创建、赋值一步到位,想不想学?

来,上边跟我一起画个 List,在你下边画一个Map……

List<String> list = new ArrayList<String>() {{  
    add("www.");  
    add("javastack.");  
    add("cn");  
}};  
  
Map<String, String> map = new HashMap<String, String>() {{  
    put("1", "www.");  
    put("2", "javastack.");  
    put("3", "cn");  
}};

哈哈,高大上的写法,栈长以前写过,写法虽然是很装X,然而并没有什么卵用。

2、算术

static {  
    final int size = -(-128) + 127 + 1;  
  
    // Load and use the archived cache if it exists  
    VM.initializeFromArchive(ByteCache.class);  
    if (archivedCache == null || archivedCache.length != size) {  
        Byte[] c = new Byte[size];  
        byte value = (byte)-128;  
        for(int i = 0; i < size; i++) {  
            c[i] = new Byte(value++);  
        }  
        archivedCache = c;  
    }  
    cache = archivedCache;  
}

注意到上面size的写法没有?

明明可以写成:

final int size = 256;

他非要写成:

final int size = -(-128) + 127 + 1;

这么装 B 的写法来自 JDK 包装类java.lang.Byte里面的静态方法。

为什么要这么写呢?

这样的写法在 JDK 里面有很多,大家看到这些写法都会觉得很奇怪,曾有粉丝问我这是为什么。

真正缘由无从考察,但栈长我觉得写 JDK 的大神其实就想告诉你,Byte 的 256 个数是由 -128 ~ 127 这个范围组成的,起到一个标识数字范围的作用而已。至少 Byte 为什么取这个范围,为什么byte取值-128~127??这篇文章可以解密。

如果你知道其中的更多道道,欢迎留言分享!

3、移位

/**  
 * The default initial capacity - MUST be a power of two.  
 */  
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16  
  
/**  
 * The maximum capacity, used if a higher value is implicitly specified  
 * by either of the constructors with arguments.  
 * MUST be a power of two <= 1<<30.  
 */  
static final int MAXIMUM_CAPACITY = 1 << 30;

这两个变量来自java.util.HashMap源码,你可能也非常好奇为什么不直接写成数字,要弄一个移位骚操作?

这是在告诉开发者,HashMap 的容量大小必须是 2 的幂次,不然会造成空间浪费。

4、复制变量

transient Collection<V> values;  
  
public Collection<V> values() {  
    Collection<V> vs = values;  
    if (vs == null) {  
        vs = new Values();  
        values = vs;  
    }  
    return vs;  
}

以上同样来自java.util.HashMap的源码,为什么不直接用values:

transient Collection<V> values;  
  
public Collection<V> values() {  
    if (values == null) {  
        values = new Values();  
    }  
    return values;  
}

而要重新定义一个vs来绕一个弯呢?

这样写不是更简单么?

JDK里面大量这样的写法,这是为什么呢?!

那是因为操作局部变量要比读取全局变量要更快,另外,我个人觉得还有一个好处,再申明一下局部变量,可以很明显的看到这个变量的类型,而不要翻到上面或者用鼠标移上去来看变量类型。

另外提一点,上面的复制变量再操作的方式让我想到了CopyOnWriteArrayList,这也是让当前变量不被其他线程改变保证当前线程变量一致性的一种方式。

写 JDK 源码的都是大神啊,透过源码,我们能学到太多东西!

5、泛型

来看一段泛型的灵活运用:

public <R> Observable<R> compose(Transformer<? super T, ? extends R> transformer) {  
    return ((Transformer<T, R>) transformer).call(this);  
}

这个泛型方法写得牛 X 吧,泛型 T、R、通配符(?)、上边界(extends)和下边界(super)都用上了!

常用的泛型含义:

  • T - Type(类型)
  • R - Result(结果)
  • K - Key(键)
  • V - Value(值)
  • E - Element (元素)
  • N - Number(数字)
  • ? - 不确定类型

上面的泛型我们应该有常见到吧,边界和通配符不懂的可以看下这篇文章吧:困扰我多年的Java泛型 和 ,终于搞清楚了。

泛型要学会用,学好能装B。

6、Lambda

Lambda 表达式这是 Java 8 里面添加的新特性,用来简化匿名内部类以及结合函数式接口编程用的。

如下面创建线程的示例:

// 1  
Runnable runnable = () -> System.out.println("javastack.cn");  
new Thread(runnable).start();  
  
// 2  
new Thread(() -> System.out.println("javastack.cn")).start();  
  
// 3  
new Thread(() -> clean()).start();

三个不同的写法,我们再也不用写new Runnable()的一大堆 的匿名内部类了,是不是很清爽了!

下面是一个Lambada真实案例:

@Bean  
public CommandLineRunner commandLineRunner(NettyServer nettyServer) {  
    return (args) -> {  
        Thread thread = new Thread(() -> nettyServer.start());  
        thread.setDaemon(true);  
        thread.start();  
    };  
}

上述示例省去了 newCommandLineRunner的匿名内部类的过程。

7、函数式编程

来看一个真实的案例,来自 Spring Boot 的邮件发送自动配置:

private void applyProperties(JavaMailSenderImpl sender) {  
    PropertyMapper map = PropertyMapper.get();  
    map.from(this.properties::getHost).to(sender::setHost);  
    map.from(this.properties::getPort).whenNonNull().to(sender::setPort);  
    map.from(this.properties::getUsername).to(sender::setUsername);  
    map.from(this.properties::getPassword).to(sender::setPassword);  
    map.from(this.properties::getProtocol).to(sender::setProtocol);  
    map.from(this.properties::getDefaultEncoding).whenNonNull().as(Charset::name)  
            .to(sender::setDefaultEncoding);  
    map.from(this.properties::getProperties).whenNot(Map::isEmpty)  
            .as(this::asProperties).to(sender::setJavaMailProperties);  
}

第一次看到这段代码的时候,我内心是拒绝的,很难理解。

上面的 from 和 to 方法分别用到了Supplier和Consumer函数式接口,还用到了双冒号::结合使用,讳莫如深,还能结合Lambda表达式使用。

函数式编程很厉害,虽然会用,但到现在我也觉得很高深,可读性和可理解性太差了,但是,装 X 必学、必用。

8、流关闭

MyInputStream mis = new MyInputStream();  
MyOutputStream mos = new MyOutputStream();  
try (mis; mos) {  
    mis.read("1.9");  
    mos.write("1.9");  
} catch (Exception e) {  
    e.printStackTrace();  
}

没错,你看到的这个关闭流骚操作是 Java 9 的新语法糖,较 Java 7 又简化了try-with-resources用法,装 X 的姿势越来越多了。

不知道的可能上来就一顿骂了,你流关闭动作在哪,为什么不关闭流,多跟着栈长学点新知识吧,哈哈。

9、类型推断

老读者应该都看过,Java 10 刚出来的时候,我写过两篇新特性文章:

  • Java 10的10个新特性,将彻底改变你写代码的方式!
  • Java 10 实战第 1 篇:局部变量类型推断

来,我再挑两个示例来欣赏下:

示例1:

var javastack = "javastack";

示例2:

private static void testLoop() {  
    for (var i = 0; i < 3; i++) {  
        for (var m = 10; m < 15; m++) {  
            System.out.println(i + m);  
        }  
    }  
}

这样写会不会被打?也太省事了!

类型推断出来后,都说 Java 越来越像 Javascript 了,其实就是 Java 10 增加的一种语法糖而已,在编译期间会自动推断实际类型,其编译后的字节码和实际类型一致。

10、模式匹配

instanceof模式是匹配这是 Java 14 推出来的新特性:

if (object instanceof Kid kid) {  
    // ...  
} else if (object instanceof Kiddle kiddle) {  
    // ...  
}

匹配后直接创建对象和赋值直接拿来用,不需要再添加强制转换的代码,大大提高了可读性和安全性。具体可以看这篇文章:Java 14 之模式匹配,非常赞的一个新特性!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • 1、集合初始化 集合的创建、赋值一步到位,想不想学? 来,上边跟我一起画个 List,在你下边画一个Map…… L...
    Java程序员YY阅读 203评论 0 0
  • 抽象,继承,封装,多态 下面将一一解释.抽象是将一类对象的共同特征总结出来构造类的过程.包括数据抽象和行为抽象两部...
    高珊珊aim阅读 955评论 0 0
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,422评论 0 4
  • 作为当今使用最广泛的编程语言之一的 Java 在 2018 年 3 月 21 日发布了第十个大版本。为了更快地迭代...
    ecb403396fec阅读 281评论 0 0
  • 又是美好的一天! 感赏儿子坚持完成作业,是个有责任心的男孩! 感赏儿子用心料理野采回来的植物,还向我介...
    yesiqin阅读 120评论 2 2