专栏首页码匠的流水账java10系列(二)Local-Variable Type Inference

java10系列(二)Local-Variable Type Inference

本文主要解读下java10的Local-Variable Type Inference

实例

    @Test
    public void testVar(){
        var list = List.of(1,2,3,4,5);
        var strList = list.stream()
                .map(e -> "hello" + e)
                .collect(Collectors.toList());
        var result = strList.stream()
                .collect(Collectors.joining(","));
        System.out.println(result);
    }

    @Test
    public void testVarInForEach(){
        var data = Map.of("k1",1,"k2",2,"k3",3,"k4",4,"k5",5);
        for(var entry : data.entrySet()){
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }

    @Test
    public void testVarInTry() throws IOException {
        try(var input = this.getClass().getClassLoader().getResourceAsStream("demo.txt")) {
            int data = input.read();
            while(data != -1){
                System.out.print((char) data);
                data = input.read();
            }
        }
    }

引入的var只是为了简化代码,注意var只能用于局部变量。它不能用于类成员变量,方法参数等。

Style Guidelines

引入var是一把双刃剑,一方面简化了代码,但是同时可能影响了可读性,特别是那些你不熟悉的类型。为此Stuart W. Marks给出了一份使用指南Style Guidelines for Local Variable Type Inference in Java。其主要观点如下:

主要原则

  • 阅读代码比编写代码更重要
  • 使用var应当让读者能够清楚推断出类型
  • 代码可读性不应该依赖于IDE
  • 显式类型是一种折衷,虽然有时候冗长,但是类型清晰

var使用指南

  • 变量名称要提供有用信息
// ORIGINAL
List<Customer> x = dbconn.executeQuery(query);
// GOOD
var custList = dbconn.executeQuery(query);
  • 尽量减少局部变量的范围
var items = new HashSet<Item>(...);

// ... 100 lines of code ...

items.add(MUST_BE_PROCESSED_LAST);
for (var item : items) ...

var的声明与使用距离太远,不容易看清楚items的类型

  • 考虑var初始化时向读者提供足够的信息
// ORIGINAL
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

// GOOD
var outputStream = new ByteArrayOutputStream();

比如右侧是显示类型,非常清晰

  • 用于使用var局部变量分解链接或嵌套的表达式
Map<String, Long> freqMap = strings.stream()
                                   .collect(groupingBy(s -> s, counting()));
Optional<Map.Entry<String, Long>> maxEntryOpt = freqMap.entrySet()
                                                       .stream()
                                                       .max(Map.Entry.comparingByValue());
return maxEntryOpt.map(Map.Entry::getKey);

可以用var声明中间变量

var freqMap = strings.stream()
                     .collect(groupingBy(s -> s, counting()));
var maxEntryOpt = freqMap.entrySet()
                         .stream()
                         .max(Map.Entry.comparingByValue());
return maxEntryOpt.map(Map.Entry::getKey);
  • 对于钻石语法及泛型要小心
// OK: both declare variables of type PriorityQueue<Item>
PriorityQueue<Item> itemQueue = new PriorityQueue<>();
var itemQueue = new PriorityQueue<Item>();

// DANGEROUS: infers as PriorityQueue<Object>
var itemQueue = new PriorityQueue<>();

// DANGEROUS: infers as List<Object>
var list = List.of();

// OK: itemQueue infers as PriorityQueue<String>
Comparator<String> comp = ... ;
var itemQueue = new PriorityQueue<>(comp);

// OK: infers as List<BigInteger>
var list = List.of(BigInteger.ZERO);
  • 使用var声明字符串/数字时要小心
// ORIGINAL
boolean ready = true;
char ch = '\ufffd';
long sum = 0L;
String label = "wombat";

// GOOD
var ready = true;
var ch    = '\ufffd';
var sum   = 0L;
var label = "wombat";

// ORIGINAL
byte flags = 0;
short mask = 0x7fff;
long base = 17;

// DANGEROUS: all infer as int
var flags = 0;
var mask = 0x7fff;
var base = 17;

// ORIGINAL
float f = 1.0f;
double d = 2.0;

// GOOD
var f = 1.0f;
var d = 2.0;

小结

var是一把双刃剑,一方面可以简化繁琐的代码,但是使用不恰当又会影响代码可读性,需要谨慎使用。

doc

  • JEP 286: Local-Variable Type Inference
  • Style Guidelines for Local Variable Type Inference in Java
  • Java 10

本文分享自微信公众号 - 码匠的流水账(geek_luandun),作者:go4it

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊HystrixConcurrencyStrategy

    hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/strategy/concurrency/Hystri...

    codecraft
  • 聊聊springboot2的ScheduledTasksEndpoint

    本文主要研究下springboot2的ScheduledTasksEndpoint

    codecraft
  • 聊聊reactive streams publisher的doOn方法

    本文主要研究一下reactive streams Publisher的doOn方法

    codecraft
  • Nodejs进阶:Express常用中间件body-parser实现解析

    body-parser是非常常用的一个express中间件,作用是对post请求的请求体进行解析。使用非常简单,以下两行代码已经覆盖了大部分的使用场景。

    IMWeb前端团队
  • JDK10的新特性:本地变量类型var

    java以面向对象的特性显著于世并得到了蓬勃的发展。在语言的发展过程中,为了让java语言更加简洁和方便使用,JDK也在不断的进行改进。

    程序那些事
  • 批量导出某个简书用户的所有文章列表和文章超链接

    虽然简书提供了批量下载文章的功能,但是下载到本地的文章都是markdown格式的,不包含文章的链接,这不满足我的需求。

    Jerry Wang
  • Js基础教程之变量及数据类型

    基本类型:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。

    老雷PHP全栈开发
  • Java 10 var关键字详解和示例教程【面试+工作】

    在本文中,我将通过示例介绍新的Java SE 10特性——“var”类型。你将学习如何在代码中正确使用它,以及在什么情况下不能使用它。

    Java帮帮
  • Arcgis for js实现北京地铁的展示

    在chrom中输入地址http://map.baidu.com/subways/index.html?c=beijing

    lzugis
  • 纯粹依靠位操作实现整数加法运算

    Jerry Wang

扫码关注云+社区

领取腾讯云代金券