Lombok之@Val和@Var使用

x33g5p2x  于2021-12-25 转载在 其他  
字(2.7k)|赞(0)|评价(0)|浏览(467)

前言:

@Val和@Var在开发过程中几乎不会使用到。但是,为了Lombok系列文章的完整性,还是将它写出来了。 读者可根据兴趣选择性学习。

一. 为什么不用@Val和@Var?

为什么不用@Val和@Var?注意是不用!
val可以作为局部变量声明的类型,而不必编写实际类型。val注解将从初始化程序表达式中推断类型。局部变量也将成为最终变量。此功能仅适用于局部变量和foreach循环,不适用于字段(实体类的成员变量)。同时,初始化表达式是必需的。
var和val的差别在于,val修饰的局部变量没有被标记为final。

二. @Val和@Var如何使用?

public class ValVarExample {
    public static void main(String[] args) {

        val name = "cauchy6317";
        var age = Integer.valueOf(12);
        System.out.println(name.getClass());
        System.out.println(age.getClass());
    }
}
// class文件反编译后的代码
public class ValVarExample {
    public ValVarExample() {
    }

    public static void main(String[] args) {
        String name = "cauchy6317";
        Integer age = 12;
        System.out.println("cauchy6317".getClass());
        System.out.println(age.getClass());
    }
}

可以看到,val修饰的name是String类型,var修饰age是Integer类型,然而反编译后的name并没有加上final修饰。但是,如果重新为name赋值,编译会出错。

可以看到,IDEA不能主动提示name重新赋值的错误,对于final直接修饰的address,重新赋值的时候IDEA会出现红色下划线的错误提示。就这一点足以让我们放弃val了,而且val和var作为变量类型最先出现在弱类型语言中,如:JavaScript。Java是一种强类型语言,在变量声明的时候就要指定变量类型。Lombok提供val和var违背了Java 的语言设计初衷,对于从事Java编程的人员来说,这样的设计让开发者很是不满。
如果有一点用处的话,可能就是对于弱类型语言的开发者使用Java更顺手一些。当然,这样也改变不了这两个注解是很糟糕设计的现象。因为更重要的原因是,val和var是根据初始化表达式的类型去生成变量类型的,如:var example = new ArrayList< String>();会生成ArrayList< String> example = new ArrayList< String>();而开发过程中更常用的是 List< String> example = new ArrayList< String>();利用父类类型作为变量类型,这是充分利用Java的多态特性。所以综上所述,val和var对于Lombok来说,至于对于使用Java的开发者来说,是很糟糕的设计。

三. @Val和@Var源码

/** * Use {@code val} as the type of any local variable declaration (even in a for-each statement), and the type will be inferred from the initializing expression. * For example: {@code val x = 10.0;} will infer {@code double}, and {@code val y = new ArrayList<String>();} will infer {@code ArrayList<String>}. The local variable * will also be made final. * <p> * Note that this is an annotation type because {@code val x = 10;} will be desugared to {@code @val final int x = 10;} * <p> * Complete documentation is found at <a href="https://projectlombok.org/features/val">the project lombok features page for &#64;val</a>. */
public @interface val {
}
/** * Use {@code var} as the type of any local variable declaration (even in a {@code for} statement), and the type will be inferred from the initializing expression * (any further assignments to the variable are not involved in this type inference). * <p> * For example: {@code var x = 10.0;} will infer {@code double}, and {@code var y = new ArrayList<String>();} will infer {@code ArrayList<String>}. * <p> * Note that this is an annotation type because {@code var x = 10;} will be desugared to {@code @var int x = 10;} * <p> * Complete documentation is found at <a href="https://projectlombok.org/features/var">the project lombok features page for &#64;var</a>. */
public @interface var {
}

四. 特别说明

本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
源码地址:gitee

相关文章