Junit、反射、注解、JDK8新特性

Junit
概述 : Junit是Java语言编写的第三方单元测试框架(工具类)
作用 : 用来做“单元测试”——针对某个普通方法,可以像main()方法一样独立运行,它专门用于测试某个方法。
Junit的使用步骤
1.在模块下创建lib文件夹,把Junit的jar包复制到lib文件夹中
2.选中Junit的jar包,右键选中 add as Library,把JUnit4的jar包添加到classPath中
3.在测试方法上面写上@Test注解
4.执行测试方法

执行测试方法
1.选中方法名—>右键—>选中执行 只执行选中的测试方法
2.选中类名----->右键—>选中执行 执行该类中所有的测试方法
3.选中模块---- ->右键—>选中all tests 执行 执行该模块中所有的测试方法

如何查看测试结果
绿色:表示测试通过
红色:表示测试失败,有问题

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

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

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

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

类的加载时机
1.创建类的实例。
2.类的静态变量,或者为静态变量赋值。
3.类的静态方法。
4.使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。
5.初始化某个类的子类。
6.直接使用java.exe命令来运行某个主类。
以上六种情况的任何一种,都可以导致JVM将一个类加载到方法区。

类加载器
类加载器:是负责将磁盘上的某个class文件读取到内存并生成Class的对象。
Java中有三种类加载器,它们分别用于加载不同种类的class:
启动类加载器(Bootstrap ClassLoader):用于加载系统类库<JAVA_HOME>\bin目录下的class,例如:rt.jar。
扩展类加载器(Extension ClassLoader):用于加载扩展类库<JAVA_HOME>\lib\ext目录下的class。
应用程序类加载器(Application ClassLoader):用于加载我们自定义类的加载器。
使用类的class对象的getClassLoader方法获得,获得上层加载器,getParent();

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

Class类常用公共方法:
String getSimpleName(); 获得类名字符串:类名
String getName(); 获得类全名:包名+类名
T newInstance() ; 创建Class对象关联类的对象
构造器相关方法:获得Constructor对象来创建类的对象。

  1. Constructor getConstructor(Class… parameterTypes)
    根据参数类型获得对应的Constructor对象。
    只能获得public修饰的构造方法
  2. Constructor getDeclaredConstructor(Class… parameterTypes)
    根据参数类型获得对应的Constructor对象
    可以是public、protected、(默认)、private修饰符的构造方法。
  3. Constructor[] getConstructors()
    获得类中的所有构造方法对象,只能获得public的
  4. Constructor[] getDeclaredConstructors()
    获得类中的所有构造方法对象
    可以是public、protected、(默认)、private修饰符的构造方法。
    Constructor对象常用方法
  5. T newInstance(Object… initargs)
    根据指定的参数创建对象
  6. void setAccessible(true)
    设置"暴力反射"——是否取消权限检查,true取消权限检查,false表示不取消,调用私有的构造方法创建实例时需要使用,设置true
    成员方法相关方法:操作Method对象来调用成员方法
    1.Method getMethod(String name,Class…args);
    根据方法名和参数类型获得对应的成员方法对象,只能获得public的
  7. Method getDeclaredMethod(String name,Class…args); 掌握
    根据方法名和参数类型获得对应的成员方法对象,包括public、protected、(默认)、private的
    3.Method[] getMethods();
    获得类中的所有成员方法对象,返回数组,只能获得public修饰的且包含父类的
  8. Method[] getDeclaredMethods(); 掌握
    获得类中的所有成员方法对象,返回数组,只获得本类的,包括public、protected、(默认)、private的
    Method对象常用方法
    1.Object invoke(Object obj, Object… args)
    调用指定对象obj的该方法
    args:调用方法时传递的参数
    2.void setAccessible(true)
    设置"暴力访问"——是否取消权限检查,true取消权限检查,false表示不取消

成员变量相关方法:通过Field对象给对应的成员变量赋值和取值
1.Field getField(String name);
根据成员变量名获得对应Field对象,只能获得public修饰
2.Field getDeclaredField(String name);
根据成员变量名获得对应Field对象,包括public、protected、(默认)、private的
3. Field[] getFields();
获得所有的成员变量对应的Field对象,只能获得public的
4. Field[] getDeclaredFields();
获得所有的成员变量对应的Field对象,包括public、protected、(默认)、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对象。

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

我们之前使用过的注解:
1).@Override:子类重写方法时——编译时起作用
2).@FunctionalInterface:函数式接口——编译时起作用
3).@Test:JUnit的测试注解——运行时起作用

注解的作用
生成帮助文档:@author和@version
执行编译期的检查 例如:@Override
框架的配置(框架=代码+配置)

自定义注解
public @interface 注解名{
属性
}

注解属性
格式:数据类型 属性名();

属性类型
1.基本类型
2.String
3.Class类型
4.注解类型
5. 枚举类型
6.以上类型的一维数组类型

使用注解:
如果一个注解中有属性,那么使用注解的时候一定要给注解属性赋值
如果一个注解没用属性,那么就不需要给注解属性赋值,直接使用即可
如何给注解属性赋值:
@注解名(属性名=值,属性名2=值2)

给注解属性赋值的注意事项
1.一旦注解有属性了,使用注解的时候,属性必须有值
2.若属性类型是一维数组的时候,当数组的值只有一个的时候可以省略{}
3.如果注解中只有一个属性,并且属性名为value,那么使用注解给注解属性赋值的时候,注解属性名value可以省略
4.注解属性可以有默认值 格式:属性类型 属性名() 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):判断指定的注解有没有。

动态代理介绍
概述 : 动态代理就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
动态代理的获取:
jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象
动态代理相关api介绍
Java.lang.reflect.Proxy类可以直接生成一个代理对象
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象
参数1:ClassLoader loader 被代理对象的类加载器
参数2:Class<?>[] interfaces 被代理对象的要实现的接口
参数3:InvocationHandler h (接口)执行处理接口
返回值: 代理对象
前2个参数是为了帮助在jvm内部生成被代理对象的代理对象,第3个参数,用来监听代理对象调用方法,帮助我们调用方法
InvocationHandler中的Object invoke(Object proxy, Method method, Object[] args)方法:调用代理类的任何方法,此方法都会执行
参数1:代理对象(慎用)
参数2:当前执行的方法
参数3:当前执行的方法运行时传递过来的参数
返回值:当前方法执行的返回值

代理方法有参数和代理多个方法

public class Test {
    public static void main(String[] args) {
        /*
            需求:
                对List接口进行代理,以前的remove(Object obj)方法是删除集合中第一次出现的元素
                (比如集合中有多个“abc”,调用remove(“abc”)后只会删除一个元素)。
                代理后,要求在调用remove(Object obj)方法后,能够删除集合中所有匹配的元素。【动态代理】
            动态代理步骤:
                1.使用Proxy调用newProxyInstance()方法动态获取代理对象
                2.在InvocationHandler中的invoke方法进行增强代理的方法
         */
        // ArrayList看成被代理类
        ArrayList<String> list = new ArrayList<>();// JinLian
        list.add("abc");
        list.add("bac");
        list.add("cba");
        list.add("abc");
        list.add("abc");
        list.add("abc");
        list.add("abc");
        System.out.println("删除前:"+list);// [abc, bac, cba, abc, abc, abc, abc]

        // 获取代理对象
        List<String> proxy = (List<String>)Proxy.newProxyInstance(list.getClass().getClassLoader(),ArrayList.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 代理对象调用方法就会来到这里
                Object res = method.invoke(list, args);

                if (method.getName().equals("remove")){
                    // 迭代器循环删除
                    Iterator<String> it = list.iterator();
                    while (it.hasNext()) {
                        String e = it.next();
                        if (e.equals(args[0])){// false
                            it.remove();
                        }
                    }
                }

                if (method.getName().equals("set")){
                    System.out.println("hhhhhhhhh....");
                }
                return res;
            }
        });

        // 代理对象.remover("abc"); //  [bac, cba]
        boolean res = proxy.remove("abc");// 拆箱
        System.out.println("res:"+res);// true
        System.out.println("删除后:"+list);// [bac, cba]


        // 调用proxy调用set方法设置值
        String res2 = proxy.set(0, "acb");
        System.out.println("res2:"+res2);// res2: bac
        System.out.println("设置后:"+list);// [bac, cba]

        // 未使用代理
        // list.remove("abc");
        // System.out.println("删除后:"+list);// [bac, cba, abc, abc, abc, abc]
    }
}

JDK8新特性
方法引用:方法引用使用一对冒号 :: , 方法引用就是用来在一定的情况下,替换Lambda表达式
使用方法引用的步骤
1.分析要写的Lambda表达式的大括号中是否就是调用另一个方法
2.如果是,就可以使用方法引用替换,如果不是,就不能使用方法引用
3.确定引用的方法类型(构造方法,成员方法,静态方法,类的成员方法)
4.按照对应的格式去引用:
构造方法: 类名::new
成员方法(有参数): 对象名::方法名
静态方法: 类名::方法名
类的成员方法\成员方法(无参数): 类名::方法名

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’作为分割。编码输出最后没有行分割。

获取编码器和解码器的方法
static Base64.Decoder getDecoder() 基本型 base64 解码器。
static Base64.Encoder getEncoder() 基本型 base64 编码器。

static Base64.Decoder getMimeDecoder() Mime型 base64 解码器。
static Base64.Encoder getMimeEncoder() Mime型 base64 编码器。

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

编码和解码的方法:

Encoder编码器: encodeToString(byte[] bys)编码
Decoder解码器: decode(String str) 解码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring JUnit5 注解测试是一种基于 JUnit5 平台的单元测试方法,通过使用 Spring 扩展提供的注解来实现依赖注入、AOP、事务控制等功能,从而方便地进行单元测试。 下面是 Spring JUnit5 注解测试常用的注解及其作用: 1. @ExtendWith(SpringExtension.class):指定运行测试的类为 SpringExtension,该类会创建 Spring 的上下文环境,并自动加载指定的配置文件或配置类。 2. @ContextConfiguration:指定 Spring 的配置文件或配置类,用于创建 Spring 的上下文环境。 3. @Autowired:自动装配 Spring 容器中的 Bean,可以省略 setter 方法。 4. @Transactional:在测试方法中添加该注解可以实现事务控制,测试方法执行完成后自动回滚事务。 5. @Test:用于标记测试方法。 下面是一个简单的 Spring JUnit5 注解测试的例子: ```java @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = AppConfig.class) @Transactional public class UserServiceTest { @Autowired private UserService userService; @Test public void testAddUser() { User user = new User(); user.setUsername("test"); user.setPassword("123456"); userService.addUser(user); User addedUser = userService.getUserByName("test"); Assertions.assertEquals("test", addedUser.getUsername()); } } ``` 在该例子中,@ExtendWith 指定了运行测试的类为 SpringExtension,@ContextConfiguration 指定了需要加载的配置类 AppConfig,@Transactional 用于进行事务控制,@Autowired 实现了依赖注入,@Test 标记了测试方法。相比于 Spring JUnit4 注解测试,Spring JUnit5 注解测试更加简洁、易读,而且支持更多的测试特性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值