java JUnit单元测试、反射、注解

1、Junit单元测试

Junit的概念

  • 概述 : Junit是Java语言编写的第三方单元测试框架(工具类)
  • 作用 : 用来做“单元测试”——针对某个普通方法,可以像main()方法一样独立运行,它专门用于测试某个方法。

Junit的使用步骤

  • 1.在模块下创建lib文件夹,把Junit的jar包复制到lib文件夹中

  • 2.选中Junit的jar包,右键选中 add as Library,把JUnit4的jar包添加到classPath中

  • 3.在测试方法上面写上@Test注解

  • 4.执行测试方法

public class Person {

    @Test
    public void test1(){
        System.out.println("Person test1 方法执行了....");
    }

    @Test
    public void test2(){
        System.out.println("Person test2 方法执行了....");
    }

}

执行测试方法

  • 1.选中方法名—>右键—>选中执行 只执行选中的测试方法

  • 2.选中类名----->右键—>选中执行 执行该类中所有的测试方法

  • 3.选中模块---- ->右键—>选中all tests 执行 执行该模块中所有的测试方法

  • 如何查看测试结果

    • 绿色:表示测试通过
    • 红色:表示测试失败,有问题

Junit单元测试的注意实现

  • 1.测试方法的权限修饰符一定是public
  • 2.测试方法的返回值类型一定是void
  • 3.测试方法一定没有参数
  • 4.测试方法 的声明之上一定要使用@Test注解

Junit其他注解

  • @Before:用来修饰方法,该方法会在每一个测试方法执行之前执行一次。
  • @After:用来修饰方法,该方法会在每一个测试方法执行之后执行一次。
  • @BeforeClass:用来静态修饰方法,该方法会在所有测试方法之前执行一次,而且只执行一次。
  • @AfterClass:用来静态修饰方法,该方法会在所有测试方法之后执行一次,而且只执行一次。

与方法的定义位置无关

Junit断言

断言:预先判断某个条件一定成立,如果条件不成立,则直接报错。 使用Assert类中的assertEquals()方法

public class Demo02 {
    @Test
    public void addTest(){
        //测试
        int add = add(3, 6);

        //断言判断结果
        //第一个参数表示期望值
        //第二个参数表示实际值
        //如果结果正确的就测试通过,如果结果错误的,就会报错
        Assert.assertEquals(9,add);
    }

    //加法
    //这个代码的语法没问题,也没有异常。他是逻辑错误,系统不知道你要算的是加法
    public int add(int a, int b){
        int sum = a * b;
        return sum;
    }
}

2、反射

2.1 类加载器

类的加载

  • 当我们的程序在运行后,第一次使用某个类的时候,会将此类的class文件读取到内存,并将此类的所有信息存储到一个Class对象中
    在这里插入图片描述

类的加载时机

  1. 创建类的实例。

  2. 访问类的静态变量,或者为静态变量赋值。

  3. 类的静态方法。

  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。

  5. 初始化某个类的子类。

  6. 直接使用java.exe命令来运行某个主类。

    以上六种情况的任何一种,都可以导致JVM将一个类加载到方法区。

public class Test {
    public static void main(String[] args) throws Exception{
        // 类的加载时机
        //  1. 创建类的实例。
        //  Student stu = new Student();

        // 2. 类的静态变量,或者为静态变量赋值。
        // Person.country = "中国";

        // 3. 类的静态方法。
        // Person.method();

        // 4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。
        // Class<?> c = Class.forName("com.it.demo1.Student");

        //  5. 初始化某个类的子类。
        // Zi zi = new Zi();

        // 6. 直接使用java.exe命令来运行某个主类。
    }
}

类加载器

类加载器:是负责将磁盘上的某个class文件读取到内存并生成Class的对象。

  • Java中有三种类加载器,它们分别用于加载不同种类的class:
    • 启动类加载器(Bootstrap ClassLoader):用于加载系统类库<JAVA_HOME>\jre\lib目录下的class,例如:rt.jar。
    • 扩展类加载器(Extension ClassLoader):用于加载扩展类库<JAVA_HOME>jre\lib\ext目录下的class。
    • 应用程序类加载器(Application ClassLoader):用于加载我们自定义类的加载器。

加载器的名字和路径都随版本的不同而变化的
还可以自定义类加载器

public class Test {
    public static void main(String[] args) {
        /*
            类加载器:
                概述:是负责将磁盘上的某个class文件读取到内存并生成Class的对象。
                如何获取类加载器:
                    类的字节码对象.getClassLoader()
         */
        // 获取Test类的类加载器
        ClassLoader c1 = Test.class.getClassLoader();
        System.out.println(c1);// AppClassLoader

        // 获取Student类的类加载器
        ClassLoader c2 = Student.class.getClassLoader();
        System.out.println(c2);// AppClassLoader

        // 获取String类的类加载器
        ClassLoader c3 = String.class.getClassLoader();
        System.out.println(c3);// null
        //API中说明:一些实现可能使用null来表示引导类加载器。 如果此类由引导类加载器加载,则此方法将在此类实现中返回null

        System.out.println("====================委派机制=================");
        System.out.println(c1.getParent());// PlatformClassLoader或者ExtClassLoader 扩展类加载器
        System.out.println(c1.getParent().getParent());// null
    }
}

2.2 反射的概述

反射的引入

  • 问题:IDEA中的对象是怎么知道类有哪些属性,哪些方法的呢?
通过反射技术对象类进行了解剖得到了类的所有成员。

反射的概念

 反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的所有成员(成员变量,成员方法,构造方法)

使用反射操作类成员的前提

要获得该类字节码文件对象,就是Class对象

反射在实际开发中的应用

* 开发IDE(集成开发环境),比如IDEA,Eclipse
* 各种框架的设计和学习 比如SpringHibernateStructMybaits....

2.3 Class对象的获取方式

  • 方式1: 通过类名.class获得
  • 方式2:通过对象名.getClass()方法获得
  • 方式3:通过Class类的静态方法获得: static Class forName(“类全名”)
    • 每一个类的Class对象都只有一个。

2.4 Class类常用方法

String getSimpleName(); 获得类名字符串:类名
String getName();  获得类全名:包名+类名
T newInstance() ;  创建Class对象关联类的对象
public class ReflectDemo02 {
    public static void main(String[] args) throws Exception {
        // 获得Class对象
        Class c = Student.class;
        // 获得类名字符串:类名
        System.out.println(c.getSimpleName());
        // 获得类全名:包名+类名
        System.out.println(c.getName());
        // 创建对象 相当于调用了空参构造方法
        Student stu = (Student) c.newInstance();
        System.out.println(stu);
    }
}

2.5 反射之操作构造方法

Constructor类概述

反射之操作构造方法的目的
    * 获得Constructor对象来创建类的对象。

Constructor类概述
    * 类中的每一个构造方法都是一个Constructor类的对象

通过反射获取类的构造方法

Class类中与Constructor相关的方法

1. Constructor getConstructor(Class... parameterTypes)
        * 根据参数类型获得对应的Constructor对象。
        * 只能获得public修饰的构造方法
 2. Constructor getDeclaredConstructor(Class... parameterTypes)
        * 根据参数类型获得对应的Constructor对象
    	* 可以是publicprotected(默认)private修饰符的构造方法。
 3. Constructor[] getConstructors()
        获得类中的所有构造方法对象,只能获得public4. Constructor[] getDeclaredConstructors()
        获得类中的所有构造方法对象
    	可以是publicprotected(默认)private修饰符的构造方法。

通过反射执行构造方法

Constructor对象常用方法
1. T newInstance(Object... initargs)
 	根据指定的参数创建对象
2. void setAccessible(true)
   设置"暴力反射"——是否取消权限检查,true取消权限检查,false表示不取消
public class Student {
    public String name;
    public int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student(String name) {
        this.name = name;
    }

    private Student(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.lang.reflect.Constructor;


public class Test {
    public static void main(String[] args) throws Exception{
        // 获取Student类的Class对象
        Class<Student> c = Student.class;

        // 获取单个构造方法
        // 获取无参数的构造方法
        Constructor<Student> con1 = c.getDeclaredConstructor();
        System.out.println(con1);

        // 获取满参构造方法
        Constructor<Student> con2 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(con2);

        // 获取私有构造方法
        Constructor<Student> con3 = c.getDeclaredConstructor(int.class);
        System.out.println(con3);

        System.out.println("================================");
        // 获取所有构造方法
        Constructor<?>[] arr1 = c.getDeclaredConstructors();
        for (Constructor<?> con : arr1) {
            System.out.println(con);
        }

        System.out.println("================================");
        // 通过执行con1表示的构造方法来创建Student对象
        Student stu1 = con1.newInstance();
        System.out.println(stu1);// Student{name='null', age=0}

        // 通过执行con2表示的构造方法来创建Student对象
        Student stu2 = con2.newInstance("张三", 18);
        System.out.println(stu2);// Student{name='张三', age=18}

        // 取消con3表示的构造方法的权限检查
        con3.setAccessible(true);

        // 通过执行con3表示的构造方法来创建Student对象
        Student stu3 = con3.newInstance(19);
        System.out.println(stu3);// Student{name='null', age=19}

    }
}

2.6 反射之操作成员方法

Method类概述

反射之操作成员方法的目的
    * 操作Method对象来调用成员方法
Method类概述
    * 每一个成员方法都是一个Method类的对象。

通过反射获取类的成员方法

Class类中与Method相关的方法

* Method getMethod(String name,Class...args);
    * 根据方法名和参数类型获得对应的构造方法对象,只能获得public* Method getDeclaredMethod(String name,Class...args);
    * 根据方法名和参数类型获得对应的构造方法对象,包括publicprotected(默认)private* Method[] getMethods();
    * 获得类中的所有成员方法对象,返回数组,只能获得public修饰的且包含父类的

* Method[] getDeclaredMethods();
    * 获得类中的所有成员方法对象,返回数组,只获得本类的,包括publicprotected(默认)private

通过反射执行成员方法

Method对象常用方法
*  Object invoke(Object obj, Object... args)
    * 调用指定对象obj的该方法
    * args:调用方法时传递的参数
    * 返回值:执行的方法的返回值
*  void setAccessible(true)
    设置"暴力访问"——是否取消权限检查,true取消权限检查,false表示不取消
public class Student {

    public void show1() {
        System.out.println("show1 方法...");
    }

    public void show2(int num) {
        System.out.println("show2 方法...num: " + num);
    }

    private void show3() {
        System.out.println("show3 方法...");
    }

    private void show4(String str) {
        System.out.println("show1 方法...str: " + str);
    }

    public int show5(int num) {
        System.out.println("show5 方法...num: " + num);
        return 100;
    }

}
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {
        // 获取Student类的Class对象
        Class<Student> c = Student.class;

        // 获取单个方法
        // 通过反射获取show1方法
        Method m1 = c.getDeclaredMethod("show1");
        System.out.println(m1);

        // 通过反射获取show2方法
        Method m2 = c.getDeclaredMethod("show2", int.class);
        System.out.println(m2);

        // 通过反射获取show3方法
        Method m3 = c.getDeclaredMethod("show3");
        System.out.println(m3);

        // 通过反射获取show4方法
        Method m4 = c.getDeclaredMethod("show4", String.class);
        System.out.println(m4);

        // 通过反射获取show5方法
        Method m5 = c.getDeclaredMethod("show5", int.class);
        System.out.println(m5);

        System.out.println("==============================");
        // 获取所有方法
        Method[] arr = c.getDeclaredMethods();
        for (Method m : arr) {
            System.out.println(m);
        }

        System.out.println("==============================");
        // 通过反射创建Student对象
        Student stu = c.newInstance();

        // 通过反射执行m1表示的show1方法
        m1.invoke(stu);

        // 通过反射执行m2表示的show2方法
        m2.invoke(stu,10);

        // 取消m3表示的方法的权限检查
        m3.setAccessible(true);

        // 通过反射执行m3表示的show3方法
        m3.invoke(stu);

        // 取消m4表示的方法的权限检查
        m4.setAccessible(true);

        // 通过反射执行m4表示的show4方法
        m4.invoke(stu,"itheima");

        // 通过反射执行m5表示的show5方法
        Object res = m5.invoke(stu, 20);// int res = stu.show5(20);
        System.out.println(res);// 100

    }
}

2.6 反射之操作成员变量

Field类概述

反射之操作成员变量的目的
    * 通过Field对象给对应的成员变量赋值和取值

Field类概述
    * 每一个成员变量都是一个Field类的对象。

通过反射获取类的成员变量

Class类中与Field相关的方法
* Field getField(String name);
    *  根据成员变量名获得对应Field对象,只能获得public修饰
* Field getDeclaredField(String name);
    *  根据成员变量名获得对应Field对象,包括publicprotected(默认)private* Field[] getFields();
    * 获得所有的成员变量对应的Field对象,只能获得public* Field[] getDeclaredFields();
    * 获得所有的成员变量对应的Field对象,包括publicprotected(默认)private

通过反射访问成员变量

Field对象常用方法
void  set(Object obj, Object value) 
void setInt(Object obj, int i) 	
void setLong(Object obj, long l)
void setBoolean(Object obj, boolean z) 
void setDouble(Object obj, double d) 

Object get(Object obj)  
int	getInt(Object obj) 
long getLong(Object obj) 
boolean getBoolean(Object ob)
double getDouble(Object obj) 

void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
Class getType(); 获取属性的类型,返回Class对象。

setXxx方法都是给对象obj的属性设置使用,针对不同的类型选取不同的方法。

getXxx方法是获取对象obj对应的属性值的,针对不同的类型选取不同的方法。

3、注解

注解概述

  • 注解(annotation),是一种代码级别的说明,和类 接口平级关系.

    • 注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,以后,javac编译器、开发工具和其他程序可以通过反射来了解你的类及各种元素上有无标记,看你的程序有什么标记,就去干相应的事

    • 我们之前使用过的注解:

      ​ 1).@Override:子类重写方法时——编译时起作用

      ​ 2).@FunctionalInterface:函数式接口——编译时起作用

      ​ 3).@Test:JUnit的测试注解——运行时起作用

注解的作用

  • 生成帮助文档**:**@author和@version

  • 执行编译期的检查 例如:@Override

  • 框架的配置(框架=代码+配置)

开发中,我们一般都是使用注解
注解用在“源码中”,作为一个“标记”。给“注解解析器”看的,告诉“注解解析器”怎样编译、运行下面的代码。

JDK提供的三个基本的注解

​ @Override:描述方法的重写.

​ @SuppressWarnings:压制\忽略警告.

​ @Deprecated:标记过时

@SuppressWarnings("all")
class Fu{
    public void show(){

    }
}
class Zi extends Fu{
    @Override
    public void show(){

    }
}
public class Demo {
    public static void main(String[] args) {
        /*
            JDK提供的三个基本的注解:
                	@Override:描述方法的重写.
                    @SuppressWarnings:压制\忽略警告.
                    @Deprecated:标记过时
         */
        @SuppressWarnings("all")
        int num;
    }

    @Deprecated
    public static void method1(){

    }

    public static void method2(){

    }
}

自定义注解

自定义注解语法

public @interface 注解名{
     属性
}
  • 示例代码
/**
 * 定义了注解
 *
 */
public @interface Annotation01 {

}

注解属性

格式

  • 数据类型 属性名();

属性类型

​ 1.基本类型

​ 2.String

​ 3.Class类型

​ 4.注解类型

​ 5. 枚举类型

​ 6.以上类型的一维数组类型

  • 示例代码
public @interface Annotation01 {
    // 1.基本数据类型(4类8种)
    int a();
    double b();

    // 2.String类型
    String c();

    // 3.Class类型
    Class d();

    // 4.注解类型
    Annotation02 f();
    
    // 5.枚举类型
    Sex e();
    // 6.以上类型的一维数组类型
    int[] g();
    double[] h();
    String[] i();
    Sex[] j();
    Annotation02[] k();
}

使用注解

使用注解:
        如果一个注解中有属性,那么使用注解的时候一定要给注解属性赋值
        如果一个注解没有属性,那么就不需要给注解属性赋值,直接使用即可
如何给注解属性赋值:
        @注解名(属性名=,属性名2=2) 
@MyAnnotation1
@MyAnnotation2(name="张三",age=18,arr={"it1","it2"})
public class Test1 {
    @MyAnnotation1
    String str;

    @MyAnnotation1
    @MyAnnotation2(name="张三",age=18,arr={"it1","it2"})
    public static void main(String[] args) {
        /*
            注解使用:
                不带属性的注解:@注解名
                带属性的注解: @注解名(属性名=属性值,属性名=属性值,...)
                
            注意:带有属性的注解在使用的时候一定要给属性赋值,并且所有属性都要赋值
         */
        @MyAnnotation1
        @MyAnnotation2(name="张三",age=18,arr={"it1","it2"})
        int num = 10;
    }
}

给注解属性赋值的注意事项

  • 一旦注解有属性了,使用注解的时候,属性必须有值
  • 若属性类型是一维数组的时候,当数组的值只有一个的时候可以省略{}
  • 如果注解中只有一个属性,并且属性名为value,那么使用注解给注解属性赋值的时候,注解属性名value可以省略
  • 注解属性可以有默认值 格式:属性类型 属性名() default 默认值;

元注解

什么是元注解

​ 定义在注解上的注解

常见的元注解

​ @Target:表示该注解作用在什么上面(位置),默认注解可以在任何位置. 值为:ElementType的枚举值

​ METHOD:方法

​ TYPE:类 接口

​ FIELD:字段

​ CONSTRUCTOR:构造方法声明

​ @Retention:定义该注解保留到那个代码阶段, 值为:RetentionPolicy类型,默认只在源码阶段保留

​ SOURCE:只在源码上保留(默认)

​ CLASS:在源码和字节码上保留

​ RUNTIME:在所有的阶段都保留

.java (源码阶段) ----编译—> .class(字节码阶段) ----加载内存–> 运行(RUNTIME)

注解解析

java.lang.reflect.AnnotatedElement接口: Class、Method、Field、Constructor等实现了AnnotatedElement

  • T getAnnotation(ClassannotationType):得到指定类型的注解引用。没有返回null。

  • boolean isAnnotationPresent(Class<?extends Annotation> annotationType):判断指定的注解有没有。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
    String name();

    int age();

}


public class Test {

    @MyAnnotation1(name="张三",age=18)
    public void show1(){
        System.out.println("show1方法执行了....");
    }

    public void show2(){
        System.out.println("show2方法执行了....");
    }

    public static void main(String[] args) throws Exception{
        /*
            java.lang.reflect.AnnotatedElement接口: Class、Method、Field、Constructor等实现了AnnotatedElement
            - T getAnnotation(Class<T> annotationType):得到指定类型的注解引用。没有返回null。
            - boolean isAnnotationPresent(Class<?extends Annotation> annotationType):判断指定的注解有没有。

         */
        // 需求:1.获取show1方法上面的注解对象
        // 1.1 得到Test类的Class对象
        Class<?> c = Class.forName("com.it.demo12_注解解析.Test");

        // 1.2 获得show1方法的Method对象
        Method show1M = c.getDeclaredMethod("show1");

        // 1.3 根据Method对象调用getAnnotation()方法得到注解对象
        MyAnnotation1 a1 = show1M.getAnnotation(MyAnnotation1.class);
        System.out.println(a1.name());
        System.out.println(a1.age());

        System.out.println("======================");

        // 2.需求: 判断某个方法上是否有MyAnnotation1注解
        // 判断show1方法上是否有MyAnnotation1注解
        boolean res1 = show1M.isAnnotationPresent(MyAnnotation1.class);
        System.out.println(res1);// true

        // 判断show2方法上是否有MyAnnotation1注解
        Method show2M = c.getDeclaredMethod("show2");
        boolean res2 = show2M.isAnnotationPresent(MyAnnotation1.class);
        System.out.println(res2);// false

    }
}

4、动态代理

见设计模式

5、JDK8新特性

5.1 方法引用

方法引用概述

  • 方法引用使用一对冒号 :: , 方法引用就是用来在一定的情况下,替换Lambda表达式

方法引用基本使用

  • 使用场景:
    • 如果一个Lambda表达式大括号中的代码和另一个方法中的代码一模一样,那么就可以使用方法引用把该方法引过来,从而替换Lambda表达式
    • 如果一个Lambda表达式大括号中的代码就是调用另一方法,那么就可以使用方法引用把该方法引过来,从而替换Lambda表达式
public class Test {

    public static void show(){
        System.out.println("线程执行了");
    }

    public static void main(String[] args) {
        /*
            方法引用:
                概述:方法引用使用一对冒号 :: , 方法引用就是用来在一定的情况下,替换Lambda表达式
                使用场景:
                    1.如果Lambda表达式的大括号中的代码和另一个方法的方法体一模一样,那么就可以使用方法引用把该方法
                       直接引过来,从而替换Lambda表达式
                    2.如果Lambda表达式的大括号中的代码就是调用另一个方法,那么就可以使用方法引用把该方法
                       直接引过来,从而替换Lambda表达式
         */
        // 创建并启动线程
        new Thread(()->{
            System.out.println("线程执行了");
        }).start();

        // 发现上述的Lambda表达式大括号中的内容和Test类的show方法的方法体一模一样,符合方法引用替换Lambda表达式的场景
        new Thread(Test::show).start();

        System.out.println("=========================================");

        new Thread(()->{
            Test.show();
        }).start();

        // 发现上述的Lambda表达式大括号中的内容就是调用Test类的show方法,符合方法引用替换Lambda表达式的场景
        new Thread(Test::show).start();
    }
}

方法引用的分类

构造方法引用

/*构造方法的引用: 类名::new

            方法引用使用步骤:
                1.分析Lambda表达式大括号中的代码是否就是调用某个方法
                2.如果是,就使用方法引用替换Lambda表达式,如果不是,就不能替换
                3.分析引用的方法的类型
                4.确定方法的类型后,根据该方法引用的格式来引用即可
        构造方法: 类名::new
        静态方法: 类名::方法名
        成员方法(有参数): 对象名::方法名
        类的成员方法\成员方法(无参数):  类名::方法名
      */          
public class Test2 {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> list = new ArrayList<>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");

        // 需求: 把集合中的元素转换为Person对象,打印输出
        list.stream().map(s-> new Person(s)).forEach(s-> System.out.println(s));

        System.out.println("======================");
       
        list.stream().map(Person::new).forEach(s-> System.out.println(s));
	
    }
}
静态方法引用
//静态方法引用: 类名::方法名
public class Test2 {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> list = new ArrayList<>();
        list.add("110");
        list.add("111");
        list.add("112");

        // 需求:把集合中的元素转换为int类型,打印输出
        list.stream().map(s-> Integer.parseInt(s)).forEach(s-> System.out.println(s));

        System.out.println("======================");

        list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));

    }
}
对象成员方法引用
  • 成员方法有参数
        /*
            对象成员方法引用带参数: 对象名::方法名
         */
public class Test2 {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> list = new ArrayList<>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");

        // 需求:把集合中所有元素打印输出
        list.stream().forEach(s-> System.out.println(s));

        System.out.println("=================================");
        
        list.stream().forEach(System.out::println);

    }
}
类的成员方法引用
  • 成员方法没有参数
        /*
            对象成员方法引用不带参数: 类名::方法名
         */
public class Test2 {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> list = new ArrayList<>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");

        // 需求: 把集合中的元素转换为该元素对应的字符长度,打印输出
        list.stream().map(s->s.length()).forEach(System.out::println);

        System.out.println("=================================");
		//会默认的用参数s去调用String类中的length()方法
        list.stream().map(String::length).forEach(System.out::println);

    }
}

5.2 Base64

Base64概述

  • Base64是jdk8提出的一个新特性,可以用来进行按照一定规则编码和解码

Base64编码和解码的相关方法

  • 编码的步骤:

    • 获取编码器
    • 调用方法进行编码
  • 解码步骤:

    • 获取解码器
    • 调用方法进行解码
  • Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:

    • **基本:**输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
    • **URL:**输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
    • **MIME:**输出映射到MIME友好格式。输出每行不超过76字符,并且使用’\r’并跟随’\n’作为分割。编码输出最后没有行分割。
  • 获取编码器和解码器的方法

Base64方法如下:

static Base64.Decoder getDecoder() 基本型 base64 解码器
static Base64.Encoder getEncoder() 基本型 base64 编码器

static Base64.Decoder getUrlDecoder() Url型 base64 解码器
static Base64.Encoder getUrlEncoder() Url型 base64 编码器

static Base64.Decoder getMimeDecoder() Mime型 base64 解码器
static Base64.Encoder getMimeEncoder() Mime型 base64 编码器
  • 编码和解码的方法:
Encoder编码器:  encodeToString(byte[] bys)编码
Decoder解码器:  decode(String str) 解码

案例演示

public class Test1 {
    public static void main(String[] args) {
        // 使用基本型的编码器和解码器对数据进行编码和解码:
        // 1.获取编码器
        Base64.Encoder encoder = Base64.getEncoder();

        // 2.对字符串进行编码
        String str = "name=中国?password=123456";
        String str1 = encoder.encodeToString(str.getBytes());

        // 3.打印输出编码后的字符串
        System.out.println("编码后的字符串:"+str1);

        // 4.获取解码器
        Base64.Decoder decoder = Base64.getDecoder();

        // 5.对编码后的字符串进行解码
        byte[] bys = decoder.decode(str1);
        String str2 = new String(bys);

        // 6.打印输出解码后的字符串
        System.out.println("解码后的字符串:"+str2);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值