Java8特性总结(三)接口方法,注解,日期,Base64_接口注释 @日期-程序员宅基地

技术标签: java  Java基础  base64  

导航

Java8特性总结(一)概述
Java8特性总结(二)Lambda表达式,函数式接口,方法引用
Java8特性总结(三)接口方法,注解,日期,Base64

前言

这几个知识点相对内容较少,放到一篇文章里介绍。

接口方法

接口方法如何写,大家都知道了,很简单。
谈到接口方法,那就难免不谈谈他的继承关系。

多个接口

Java是可以实现多个接口的,那这个时候实现的多个接口有同名,同参的接口方法会发生什么情况呢。
接下来我们就通过代码示例,展开分析一下。

接口IA,
两个子接口IB1,IB2,
实现了IB1和IB2的类CC,
继承了IB1,IB2的接口IC, 大致就是3层关系。

代码:

public interface IA
{
    
    default void print(String str)
    {
        System.out.println(this.getClass()+".print() IA "+str);
    }
}

public interface IB1 extends IA
{
    
}

public interface IB2 extends IA
{
    
}

public interface IC extends IB1,IB2
{
       
}

public class C implements IB1, IB2
{
    
    public static void main(String[] args)
    {
        new C().print("test");

    }
}

1:IA的默认方法print(),IB1,IB2没有Override print().
这种情况一切正常,没有任何问题,最后执行C的输出是:

class my.test.java8.second.interfaceMethod1.C.print() IA test

2:IA定义默认方法print(),IB1 Override了print().

public interface IB1 extends IA
{
    
    default void print(String str)
    {
        System.out.println(this.getClass()+".print() IB1 "+str);
    }
}

这种情况也是正常,编译器也没有报任何错误,最后是C的输出

class my.test.java8.second.interfaceMethod1.C.print() IB1 test

发现输出调用的是IB1的默认方法。

可以得出结论,实现类只在乎离自己最近的那个接口的默认方法。

3:IA定义了默认方法print(),IB1和IB2分别Override。

public interface IB2 extends IA
{
    
    default void print(String str)
    {
        System.out.println(this.getClass()+".print() IB2 "+str);
    }
}

出事了,IC和C都报错了,因为编译器已经混乱了,不知道该调用IB1的方法还是IB2的方法。
Java给出的解决问题的办法就是每个子类Override这个方法,告诉编译器,我不调用别人的,我调用我自己的方法。

为C类添加函数,类似的也给IC添加。

@Override
public void print(String str)
{
    IB1.super.print(str);
    IB2.super.print(str);
}

编译过去了,看看输出吧

class my.test.java8.second.interfaceMethod1.C.print() IB1 test
class my.test.java8.second.interfaceMethod1.C.print() IB2 test

我们分别调用了两个父接口的默认方法。
当然我们也可以在方法中自己实现。

父类和接口

接下来就是继承类,实现接口,接口和类有同名,同参函数的情况了。

接口IA;
类CA;
抽象类ACA;
类CB1继承CA,实现IA;
类CB2继承ACA,实现IA。

public interface IA
{
    
    default void print(String str)
    {
        System.out.println(this.getClass()+".print() IA  "+str);
    }
}
public class CA
{
    
    public void print(String str)
    {
        System.out.println(this.getClass()+".print() CA  "+str);
    }
}
public abstract class ACA
{
    
    public abstract void print(String str);
}
public class CB1 extends CA implements IA
{
    
    public static void main(String[] args)
    {
        new CB1().print("hello");
    }
}
public class CB2 extends ACA implements IA
{
    

}

CB2直接报错。必须要Override print()方法。
修改CB2

public class CB2 extends ACA implements IA
{
    

    @Override
    public void print(String str)
    {       
    }
}

运行CB1.输出如下

class my.test.java8.second.interfaceMethod2.CB1.print() CA  hello

调用的是父类的方法。

可以得出结论,父类的方法优先于接口。

注解的变化

注解的变化还是比较小,增加了可以反复添加注解的功能。
通过代码来看看如何实现。
在一个注解中使用另外一个注解数组,这个以前版本是支持的

@Retention(RetentionPolicy.RUNTIME)
public @interface Student
{
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
public @interface Classes
{
    Student[] value();
}

实际使用情况

@Classes({
   @Student("李壮"),@Student("王静")})
public class MyClasses
{
    

}

现在的版本可以写成这样。和上面的写法是等价的。

@Student("李壮")
@Student("王静")
public class MyClasses
{
    

}

编译器报错了!提示我们@Student不是一个repeatabel的注解。
@Repeatable这个注解的注释说的很清楚,value必须是当前注解的注解集合。
如下所示:

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Classes.class)
public @interface Student
{
    
    String value();
}

改成这样错误消失。

打印测试一下结果。

public static void main(String[] args)
{
    Student student=MyClasses.class.getAnnotation(Student.class);
    System.out.println(student);

    Student[] students=MyClasses.class.getAnnotationsByType(Student.class);
    Arrays.asList(students).stream().forEach(e->System.out.println(e.value()));

    Classes classes=MyClasses.class.getDeclaredAnnotation(Classes.class);
    Arrays.asList(classes.value()).stream().forEach(e->System.out.println(e.value()));

}    

可以看出现在这种重复的注解方式,实际上是隐式的包装成Classes。
这个知识点使用较少,也就Mark一下,以备不时之需。

Base64

Base64编码引入了标准包里,使用更方便了。
以前版本使用Base64一般会用第三方的类。
比如我常用apache 的 commmon-codec.jar里Base64进行编码和解码。

String base64String = "I am  base64";  
byte[] result = Base64.encodeBase64(base64String.getBytes());

当然还有一些其他的。
现在直接使用Java自己的,而且据说也是效率最高的。

import java.util.Base64;

public class Base64Test
{
    

    public static void main(String[] args) throws Exception
    {
        String base64String = "I am  base64";  
        String encoded=Base64.getEncoder().encodeToString(base64String.getBytes("UTF-8"));
        String end=new String(Base64.getDecoder().decode(encoded),"UTF-8");
        System.out.println(encoded);
        System.out.println(end);
    }

}

日期

新的时间变化包括有。
LocalDate,LocalTime,LocalDateTime,Clock,时区的概念,时间差的概念。

LocalDate

public class LocalDateTest
{
    

    public static void main(String[] args)
    {
        LocalDate today = LocalDate.now();
        LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
        LocalDate yesterday = tomorrow.minusDays(2);
        System.out.println(tomorrow);
        System.out.println(yesterday);

        LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
        DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();
        System.out.println(dayOfWeek); // FRIDAY
    }

}   

输出结果

2017-01-20
2017-01-18
FRIDAY

直观的感觉运算比以前简单了不少。

LocalTime

public class LocalTimeTest
{
    

    public static void main(String[] args)
    {

        LocalTime time=LocalTime.now();
        System.out.println(time);
        System.out.println(time.minusHours(1));
        System.out.println(time.minusMinutes(10));
        System.out.println(time.plusHours(10));
        LocalTime late = LocalTime.of(23, 59, 59);
        System.out.println(late); // 23:59:59       
    }
}

输出结果

14:22:14.033
13:22:14.033
14:12:14.033
00:22:14.033
23:59:59

感觉运算好方便。

LocalDateTime

public class LocalDateTimeTest
{
    

    public static void main(String[] args)
    {
        LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59);

        DayOfWeek dayOfWeek = sylvester.getDayOfWeek();
        System.out.println(dayOfWeek);      // WEDNESDAY

        Month month = sylvester.getMonth();
        System.out.println(month);          // DECEMBER

        long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY);
        System.out.println(minuteOfDay);    // 1439

        LocalDateTime localdt=LocalDateTime.now();
        System.out.println(localdt);

    }

}

输出结果

WEDNESDAY
DECEMBER
1439
2017-01-19T14:23:34.938

ZoneId时区

public class TimeZoneTest
{
    
    public static void main(String[] args)
    {
        //打印所有的时区
        System.out.println(ZoneId.getAvailableZoneIds());

        ZoneId zone1 = ZoneId.of("Europe/Berlin");
        ZoneId zone2 = ZoneId.of("Brazil/East");
        ZoneId zone3=ZoneId.of("Asia/Shanghai");
        System.out.println(zone1.getRules());
        System.out.println(zone2.getRules());
        System.out.println(zone3.getRules());

        LocalTime now2 = LocalTime.now(zone2);
        LocalTime now1 = LocalTime.now(zone1);      

        System.out.println(now1);
        System.out.println(now2);

        System.out.println(now1.isBefore(now2));  // false

        long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
        long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);

        System.out.println(hoursBetween);       // -3
        System.out.println(minutesBetween);     // -239

    }
}

打印结果

[Asia/Aden, America/Cuiaba, 。。。。。 Europe/Monaco]//太长了
ZoneRules[currentStandardOffset=+01:00]东一区
ZoneRules[currentStandardOffset=-03:00]西三区
ZoneRules[currentStandardOffset=+08:00]东八区
07:24:39.798
04:24:39.798
false
-3
-180

Clock

public class ClockTest
{
    
    public static void main(String[] args)
    {
        Clock clock = Clock.systemDefaultZone();
        long millis = clock.millis();
        System.out.println(millis);

        Instant instant = clock.instant();
        Date legacyDate = Date.from(instant);   // legacy java.util.Date
        System.out.println(legacyDate);
    }
}

输出

1484807586661
Thu Jan 19 14:33:06 CST 2017

和当前日期类型的转换关系,获取当前时区时间的毫秒。

Duration

public class DurationTest
{
    public static void main(String[] args)
    {
        final LocalDateTime from = LocalDateTime.of( 2014, Month.MARCH, 16, 0, 0, 0 );
        final LocalDateTime to = LocalDateTime.now();

    final Duration duration = Duration.between( from, to );
    System.out.println( "Duration in days: " + duration.toDays() );
    System.out.println( "Duration in hours: " + duration.toHours() );
    }

}

输出

Duration in days: 1040
Duration in hours: 24974

参考文章
http://www.cnblogs.com/guangshan/p/4889732.html
http://blog.csdn.net/calmspeed/article/details/44995105
http://www.importnew.com/11908.html
http://ifeve.com/java-8-tutorial-2/
http://www.importnew.com/15637.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tornadojava/article/details/54616939

智能推荐

用Tensorflow2.x实现Faster-RCNN并可视化算法流程_faster rcnn tensorflow2.x-程序员宅基地

文章浏览阅读3.9k次,点赞14次,收藏32次。基于2.0版本的tensorflow,使用VOC2007数据集实现Faster-RCNN目标检测算法。这系列Blog将尽可能的详细介绍并讲解算法的每个模块和每个函数的功能。这篇文章将作为一个总览,可视化一张图片在训练和测试过程中的经过。github:https://github.com/cmd23333/Faster-rcnn-tensorflow2.x欢迎给star ^_^对应demo文件:faster-rcnn-visualization.ipynb整个工程化的代码还是使用PyCharm,但平_faster rcnn tensorflow2.x

移动应用ios和网页应用_如何在iOS上一次移动多个应用-程序员宅基地

文章浏览阅读293次。移动应用ios和网页应用Apple doesn’t really believe in detailed instruction manuals, so some handy tricks slip through the cracks. One such trick we’ve recently discovered is that you can move multiple app icons..._ios不同页面移动软件

手机支架3d打印模型_EFL投影式光固化生物3D打印机亮点(三)模型库一键打印...-程序员宅基地

文章浏览阅读210次。投影式光固化生物3D打印具有分辨率高,打印速度快,可实现复杂结构精细打印等优点,在水凝胶/细胞高精度批量制造上具有明显优势,已逐渐成为主流的生物3D打印方法。EFL团队持续攻关,推出了系列高精度投影式光固化生物3D打印机(EFL-BP-8600/8601)。合适的打印参数选取与调试是生物3D打印成功的一大保证,而如何高效进行打印调试,则要求使用者对打印原理与工艺有较深入的理解,这无形中提..._3d打印手机支架光固化

Windows下重启MySQL数据库_windows重启mysql-程序员宅基地

文章浏览阅读2.7w次,点赞11次,收藏53次。本文介绍三种方法重启MySQL。分别是Windows的服务,cmd,管理员cmd。_windows重启mysql

windows10看不到网络计算机,今天分析Win10看不到局域网电脑的详尽解决手段-程序员宅基地

文章浏览阅读1.1w次,点赞2次,收藏16次。win10系统已经发布很久了,已经还算是比较稳定了,但还是有用户碰到了Win10看不到局域网电脑的问题,有可能我们都会遇到Win10看不到局域网电脑这样的情况吧,要是想自己学习学习解决Win10看不到局域网电脑的方法,也是可以的,小编今天解决的方法是这样:1、按 Win + R 组合键,打开运行,并输入:control 命令,确定或回车,可以快速打开控制面板,打开控制面板窗口中,点击程序下方的卸载..._win10更新 网络看不到自己

Ansys-结构动力学分析-对称循环结构模态分析学习心得_周期对称结构的模态分析-程序员宅基地

文章浏览阅读1.3k次。分析对象是转子,一种圆形薄板结构。选择单元类型是shell181,4node除了定义材料属性外,还需要定义壳单元的厚度,位置在建立基本扇区模型(几何模型),然后打开cycle section这样程序就能将基本扇区自动地生成一个完整的360°模型接着对模型进行网格划分,用四边形单元,智能网格,定义好单元大小,自由网格划分,然后mesh在菜单中打开对称循环分析扩展选项,位于接下来就是指..._周期对称结构的模态分析

随便推点

算法-前缀和与差分-程序员宅基地

文章浏览阅读606次,点赞27次,收藏14次。那么就可以把 preSum 的公式统一为,此时的 preSum[i] 表示 nums 中 iii 元素左边所有元素之和(不包含当前元素 iii)。​下面以 [1, 12, -5, -6, 50, 3] 为例,用动图讲解一下如何求 preSum。

POJ2018 Best Cow Fences-程序员宅基地

文章浏览阅读74次。我对二分的理解:https://www.cnblogs.com/AKMer/p/9737477.html题目传送门:http://poj.org/problem?id=2018我们二分一个平均数,设\(a\)数组每个数减去平均数为\(b\)数组,若\(b\)数组当中存在某一段长度大于\(k\)并且这一段权值和大于\(0\),那么说明最终平均值肯定大于我们当前二分的平均值。那么怎么求..._poj 2018 best cow fences

nginx 504 proxy_read_timeout_proxy_read_timeout 504-程序员宅基地

文章浏览阅读3.7k次。nginx中proxy_read_timeout的值调的比较小,会出现504_proxy_read_timeout 504

UVA 10817 Headmaster's Headache(01背包+状压DP)_the headmaster of springfield school is considerin-程序员宅基地

文章浏览阅读351次。Problem D: Headmaster's HeadacheTime limit: 2 secondsThe headmaster of spring Field School is considering employing some new teachers for certain subjects. There are a numb_the headmaster of springfield school is considering employing some newteache

kafka日志保留时间设置无效问题_log.retention.hours-程序员宅基地

文章浏览阅读7.6k次,点赞4次,收藏15次。背景看了网上很多文档,说是要设置log.retention.hour等等参数。默认是保留7天,但我实测下来发现日志根本没有任何变化。目前我们的kafka,一天就有400多个G,保留七天大大增加了我们的服务器成本。不生效的设置#设置日志只保留一个小时的 "log.retention.hours": 1#设置大于500M就自动删除 "log.retention.bytes": "5..._log.retention.hours

group_concat() 拼接字符串长度限制_groupconcat最大长度-程序员宅基地

文章浏览阅读4.9k次。group_concat() 拼接列的时候长度受限,字符串的长度不能超过1024,超出1024会被截断设置Mysql 配置set session group_concat_max_len = 150000;_groupconcat最大长度