2021-08-27 Hutool工具类库的应用 - yahya

克隆 - 支持泛型的克隆接口和克隆类

泛型克隆接口

泛型克隆接口:cn.hutool.core.clone,定义了一个返回泛型的成员方法,这样,实现此接口后会提示必须实现一个public的clone方法,调用父类clone方法即可;

private static class Cat implements Cloneable<Cat>{
    private String name = "miaomiao";
    private int age = 2;
    
    @Override
    public Cat clone() {
        try {
            return (Cat) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new CloneRuntimeException(e);
        }
    }
}

泛型克隆类

泛型克隆类:cn.hutool.clone.CloneSupport

实现克隆接口,依旧有不方便之处,就是必须自己实现一个public类型的clone()方法,还要调用父类(Object)的clone方法并处理异常。

private static class Dog extends CloneSupport<Dog>{
    private String name = "wangwang";
    private int age = 3;
}

使用CloneSupport的前提是没有继承任何的类,Java不支持多重继承(可以让父类继承这个类,如果可以)。如果没办法继承类,那只有实现cn.hutool.clone.Cloneable,因此hutool提供了这两种方式,任选其一,在便捷和灵活上都提供了支持。

深克隆

实现Cloneable接口后克隆的对象是浅克隆,要想实现深克隆需要使用:

ObjectUtil.cloneByStream(obj)

对象必须实现Serializable接口。

ObjectUtil同样提供一些静态方法:clone(obj)、cloneIfPossible(obj)用于简化克隆调用

工具类

对象工具 - ObjectUtil

在我们的日常使用中,有些方法是针对Object通用的,这些方法不区分何种对象,针对这些方法,Hutool封装为ObjectUtil

  1. ObjectUtil.equal - 比较两个对象是否相等,相等需满足以下条件之一
  1. obj1 == null && obj2 == null
  2. obj1.equals(obj2)
  1. ObjectUtil.length - 计算对象长度,如果是字符串调用其length方法,集合类调用其size方法,数组调用其length属性,其他可遍历对象遍历计算长度。

支持的类型包括:CharSequence、Collection、Map、Iterator、Enumeration、Array

  1. ObjectUtil.contains - 对象中是否包含元素。

支持:String、Collection、Map、Iterator、Enumeration、Array

  1. 判断是否为null

ObjectUtil.isNull
ObjectUtil.isNotNull

  1. 克隆

ObjectUtil.clone 克隆对象,如果对象实现Cloneable接口,调用其clone方法,如果实现Serializable接口,执行深度克隆,否则返回null。
ObjectUtil.cloneIfPossible 返回克隆后的对象,如果克隆失败,返回原对象
ObjectUtil.cloneByStream 序列化后拷贝流的方式克隆,对象必须实现Serializable接口

  1. 序列化和反序列化

serialize 序列化,调用JDK序列化
unserialize 反序列化,调用JDK

  1. 判断基本类型

ObjectUtil.isBasicType 判断是否为基本类型,包括包装类型和非包装类型。

身份证工具 - IdcardUtil

身份证的验证主要是正则方式(位数,数字范围等),但是中国身份证,尤其18位身份证每一位都有严格规定,并且最后一位为校验位。而我们在实际应用中,针对身份证的验证理应严格至此。于是IdcardUtil应运而生。

IdcardUtil现在支持大陆15位、18位身份证,港澳台10位身份证。

工具中主要的方法包括:

  1. isValidCard 验证身份证是否合法
  2. convert15To18 身份证15位转18位
  3. getBirthByIdCard 获取生日
  4. getAgeByIdCard 获取年龄
  5. getYearByIdCard 获取生日年
  6. getMonthByIdCard 获取生日月
  7. getDayByIdCard 获取生日天
  8. getGenderByIdCard 获取性别
  9. getProvinceByIdCard 获取省份

社会信用代码工具 - CreditCodeUtil

法人和其他组织统一社会信用代码制度,相当于让法人和其他组织拥有了一个全国统一的“身份证号”。

  1. 第一部分:登记管理部门代码1位 (数字或大写英文字母)
  2. 第二部分:机构类别代码1位 (数字或大写英文字母)
  3. 第三部分:登记管理机关行政区划码6位 (数字)
  4. 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
  5. 第五部分:校验码1位 (数字或大写英文字母)

此工具主要提供校验和随机生成。

校验:

String testCreditCode = "91310110666007217T";
// true
CreditCodeUtil.isCreditCode(testCreditCode);

随机社会信用代码:

final String s = CreditCodeUtil.randomCreditCode();

语言特性

断言-Assert

Java中有assert关键字,但是存在许多问题:

  • assert关键字需要在运行时候显式开启才能生效,否则你的断言就没有任何意义。
  • 用assert代替if是陷阱之二。assert的判断和if语句差不多,但两者的作用有着本质的区别:assert关键字本意上是为测试调试程序时使用的,但如果不小心用assert来控制了程序的业务流程,那在测试调试结束后去掉assert关键字就意味着修改了程序的正常的逻辑。
  • assert断言失败将面临程序的退出。

因此,并不建议使用此关键字。相应的,在Hutool中封装了更加友好的Assert类,用于断言判定。

Assert类更像是Junit中的Assert类,也很像Guava中的Preconditions,主要作用是在方法或者任何地方对参数的有效性做校验。当不满足断言条件时,会抛出IllegalArgumentException或IllegalStateException异常。

String a = null;
cn.hutool.lang.Assert.isNull(a);

更多方法:

  1. isTrue 是否True
  2. isNull 是否是null值,不为null抛出异常
  3. notNull 是否非null值
  4. notEmpty 是否非空
  5. notBlank 是否非空白符
  6. notContain 是否为子串
  7. notEmpty 是否非空
  8. noNullElements 数组中是否包含null元素
  9. isInstanceOf 是否类实例
  10. isAssignable 是子类和父类关系
  11. state 会抛出IllegalStateException异常

JavaBean

DynaBean:通过Java反射机制操作JavaBean,以达到动态语言的某些特性

Bean工具-BeanUtil

把一个拥有对属性进行set和get方法的类,我们就可以称之为JavaBean。

实际上JavaBean就是一个Java类,在这个Java类中就默认形成了一种规则——对属性进行设置和获得。而反之将说Java类就是一个JavaBean,这种说法是错误的,因为一个java类中不一定有对属性的设置和获得的方法(也就是不一定有set和get方法)。

Bean工具类主要是针对这些setXXX和getXXX方法进行操作,比如将Bean对象转为Map等等。

BeanUtil.isBean 方法根据是否存在只有一个参数的setXXX方法或者public类型的字段来判定是否是一个Bean对象。这样的判定方法主要目的是保证至少有一个setXXX方法用于属性注入。

boolean isBean = BeanUtil.isBean(HashMap.class);//false
  1. 内省 Introspector

把一类中需要进行设置和获得的属性访问权限设置为private(私有的)让外部的使用者看不见摸不着,而通过public(共有的)set和get方法来对其属性的值来进行设置和获得,而内部的操作具体是怎样的?外界使用的人不用知道,这就称为内省。

    BeanUtil.getPropertyDescriptors 获得Bean字段描述数组
    PropertyDescriptor[] propertyDescriptors = BeanUtil.getPropertyDescriptors(SubPerson.class);
    BeanUtil.getFieldNamePropertyDescriptorMap 获得字段名和字段描述Map
    BeanUtil.getPropertyDescriptor 获得Bean类指定属性描述

更多用法参考官方文档

空检查属性获取-OptinalBean

在嵌套对象的属性获取中,由于子对象无法得知是否为null,每次获取属性都要检查属性兑现是否为null,使得代码会变得特备臃肿,因此使用OptionalBean来优雅的链式获取属性对象值。

定义一个嵌套的bean

// Lombok注解
@Data
public static class User {
    private String name;
    private String gender;
    private School school;
    @Data
    public static class School {
        private String name;
        private String address;
    }
}

获取address属性:

User user = new User();
user.setName("hello");

// null
String addressValue = OptionalBean.ofNullable(user)
        .getBean(User::getSchool)
        .getBean(User.School::getAddress).get();

由于school对象的值为null,一般直接获取会报空指针,使用OptionalBean即可避免判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值