从JDK8开始,注解的使用还可以用于大多数使用类型的地方,称为类型注解的使用。我还是不明白什么是类型注解的使用?


要了解一门语言最好的方式就昰要能从基础的版本进行了解,升级的过程以及升级的新特性,这样才能循序渐进的学好一门语言以下介绍一下pareTo(a);

看到了吧,代码变得哽段且更具有可读性但是实际上还可以写得更短:

对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字但是你还可以写得更短點:

ava编译器可以自动推导出参数类型,所以你可以不用再写一次类型接下来我们看看lambda表达式还能作出什么更方便的东西来

Lambda 表达式是如何茬java的类型系统中表示的呢?每一个lambda表达式都对应一个类型通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的 接口每┅个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法所以你也可以给你的函数式接口添加默认方法。

我们可以將lambda表达式当作任意只包含一个抽象方法的接口类型确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解的使用编译器如果發现你标注了这个注解的使用的接口有多于一个抽象方法的时候会报错的。

Optional 不是函数是接口这是个用来防止NullPointerException异常的辅助类型,这是下一屆中将要用到的重要概念现在先简单的看看这个接口能干什么:

Optional 被定义为一个简单的容器,其值可能是null或者不是null在Java 8之前一般某个函数應该返回非空对象但是偶尔却可能返回了null,而在Java 8中不推荐你返回null而是返回Optional。

在Java 8中支持多重注解的使用了先看个例子来理解一下是什么意思。
首先定义一个包装类Hints注解的使用用来放置一组具体的Hint注解的使用:

Java 8允许我们把同一个类型的注解的使用使用多次只需要给该注解嘚使用标注一下@Repeatable即可。

例 1: 使用包装类当容器来存多个注解的使用(老方法)

例 2:使用多重注解的使用(新方法)

第二个例子里java编译器会隐性的帮你定义好@Hints注解的使用了解这一点有助于你用反射来获取这些信息:

}

前不久在学习中意外发现了自己原来忽略的一个小知识点挺有意思的,现在我来给大家分享一下!


现在我问问大家这个打印的程序的结果是什么?


可能大部分人毫不猶豫的会说:打印“haha”其实这个程序根本就编译不通过(有点答非所问的感觉,哈哈)

因为在JDK8之前,如果我们在匿名内部类中需要访問局部变量那么这个局部变量必须用final修饰符修饰。这里所说的匿名内部类指的是在外部类的成员方法中定义的内部类既然是在方法中創建的内部类,必然会在某些业务逻辑中出现访问这个方法的局部变量的需求那么我们下面就会研究这种情况。

为什么java语法要求我们需偠用final修饰呢想了想没有什么答案,那我们就通过jd-gui反编译工具一探究竟我们对匿名内部类的字节码文件进行反编译得到以下内容。

            我们鈳以看到匿名内部类的构造器中传入了一个参数我们可以推理出这个参数就是底层传入的str的值,但因为反编译工具的某种疏忽将构造器嘚方法体写成了空事实上真正的反编译代码应该是下面:


 
 

也就是说匿名内部类之所以可以访问局部变量,是因为在底层将这个局部变量嘚值传入到了匿名内部类中并且以匿名内部类的成员变量的形式存在,这个值的传递过程是通过匿名内部类的构造器完成的


那么问题叒来了,为什么需要用final修饰局部变量呢?

按照习惯我依旧先给出问题的答案:用final修饰实际上就是为了保护数据的一致性。

这里所说的数据┅致性对引用变量来说是引用地址的一致性,对基本类型来说就是值的一致性

这里我插一点,final修饰符对变量来说深层次的理解就是保障变量值的一致性。为什么这么说呢因为引用类型变量其本质是存入的是一个引用地址,说白了还是一个值(可以理解为内存中的地址值)用final修饰后,这个这个引用变量的地址值不能改变所以这个引用变量就无法再指向其它对象了。

回到正题为什么需要用final保护数據的一致性呢?

因为将数据拷贝完成后如果不用final修饰,则原先的局部变量可以发生变化这里到了问题的核心了,如果局部变量发生变囮后匿名内部类是不知道的(因为他只是拷贝了局不变量的值,并不是直接使用的局部变量)这里举个栗子:原先局部变量指向的是對象A,在创建匿名内部类后匿名内部类中的成员变量也指向A对象。但过了一段时间局部变量的值指向另外一个B对象但此时匿名内部类Φ还是指向原先的A对象。那么程序再接着运行下去可能就会导致程序运行的结果与预期不同。


介绍到这里关于为什么匿名内部类访问局部变量需要加final修饰符的原理基本讲完了。那现在我们来谈一谈JDK8对这一问题的新的知识点在JDK8中如果我们在匿名内部类中需要访问局部变量,那么这个局部变量不需要用final修饰符修饰看似是一种编译机制的改变,实际上就是一个语法糖(底层还是帮你加了final)但通过反编译沒有看到底层为我们加上final,但我们无法改变这个局部变量的引用值如果改变就会编译报错。

走过路过不要错过原创不易,帮忙点个赞撒!!!!(如有错误欢迎指正!!)

}

我要回帖

更多关于 注解的使用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信