栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

25.Junit单元测试 类加载器 反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

25.Junit单元测试 类加载器 反射

Junit单元测试

        单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性

Junit单元测试框架

        Junit是使用Java语言实现的单元测试框架,它是开源的
        Junit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法
        Junit可以生成全部方法的测试报告

1.Junit单元测试是做什么的?
        测试类中方法的正确性的


2.Junit单元测试的优点是什么?
        Junit可以选择执行哪些测试方法,可以一键执行全部测试方法的测试
        Junit可以生测试报告,如果测试良好则是绿色;如果测试失败则是红色
        单元测试中的某个方法测试失败了,不会影响其他测试方法的测试

快速入门

        1.将JUnit的jar包导入到项目中
                IDEA通常整合好了Junit框架,一般不需要导入
                如果IDEA没有整合好,需要自己手工导入如下2个Junit的jar包到模块


        2.编写测试方法:该测试方法必须是公共的无参数无返回值的非静态方法
        3.在测试方法上使用@Test注解:标注该方法是一个测试方法
        4.在测试方法中完成被测试方法的预期正确性测试
        5.选中测试方法,选择“Junit运行” ,如果测试良好则是绿色;如果测试失败是红色

 Junit常用注解(Junit 4.xxxx版本)

Junit常用注解(Junit 5.xxxx版本)

开始执行的方法:    初始化资源
执行完之后的方法: 释放资源

public class DemoJunit {
    @Test
    public void method() {
        System.out.println("method....");
    }

    //@Test
    public void show() {
        System.out.println("show...");
    }

    @Test
    public void fun() {
        System.out.println("fun...");
    }

    @Before
    public void before() {
        System.out.println("before...");
    }

    @After
    public void after() {
        System.out.println("after...");
    }
}

lombok插件
    lombok常用注解介绍:
        @Setter     生成set方法
        @Getter     生成get方法
        @EqualsAndHashCode 生成equals和hashCode方法
        @AllArgsConstructor 生成满参构造方法
        @NoArgsConstructor  生成空参构造方法
        @ToString           生成toString方法
		
        @Data     生成set方法/get方法/equals和hashCode方法/toString方法



@Data
@NoArgsConstructor
@AllArgsConstructor

public class Student {
    private String name;//姓名
    private String gender;//性别
    private int age;//年龄
    private String address;//住址
    private String email;//邮箱

    
}

类加载器

        负责将.class文件(存储的物理文件)加载在到内存中

类加载时机

        1.创建类的实例(对象)

        2.调用类的类方法

        3.访问类或者接口的类变量,或者为该类变量赋值

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

        5.初始化某个类的子类

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

用到就加载,不用就不加载

具体原理

类加载器的分类

        引导类/根类/启动类加载器(Bootstrap ClassLoader):

        C++编写,无法直接获取,JVM自带,负责加载Java平台核心库,用来加载核心类库,比如System,String等


        扩展类加载器(Ext ClassLoader)平台类加载器(Platform ClassLoader):

        负责加载JDK中一些特殊的模块,JRE的扩展目录中jar包的加载,JDK→JRE→lib→ext


        应用类加载器(App ClassLoader)系统类加载器(System ClassLoader):

        Java语言编写的,负责加载用户类路径上所指定的类库,加载我们定义的类和第三方jar包中的类

类加载器的获取与常用方法

public class DemoClassLoader {
    @Test
    public void boot() {
        //String 由BootstrapClassLoader加载,C++实现,不让我们获取
        ClassLoader c = String.class.getClassLoader();
        System.out.println(c);//null
    }

    @Test
    public void ext() {
        //由扩展类加载器加载
        //注意: DNSNameService类在jdk8存在,其它jdk版本可能就不存在了
        ClassLoader c = DNSNameService.class.getClassLoader();
        System.out.println(c);//ExtClassloader
    }

    @Test
    public void app() {
        //自己写的类由应用类加载器加载
        ClassLoader c = Demo03ClassLoader.class.getClassLoader();
        System.out.println(c);//AppClassloader

        //获取应用类加载器的委托父加载器,其实就是扩展类加载器
        ClassLoader c2 = c.getParent();
        System.out.println(c2);//ExtClassloader

        //获取扩展类加载器的委托父加载器,其实就是核心类加载器
        //但是核心类加载器是由C++编写的,不让我们获取
        ClassLoader c3 = c2.getParent();
        System.out.println(c3);//null
    }
}

反射
Java反射机制

        是在运行状态中,对是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意方法和属性
        这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制

        利用反射可以无视修饰符获取类里面所有的属性和方法
        先获取配置文件中的信息,动态获取信息并创建对象和调用方法

反射第一步:获取Class类的对象


Class类的介绍

        1.java源文件是给程序员看的,必须翻译生成对应的.class文件才能让虚拟机看明白,class文件中存储的是01,所以.class称为字节码文件

        2.java文件等效class文件

        3.java面向对象,.class文件也是一种事务,可以定义类,然后创建对象,所以在java中有java.lang.Class类就是用来描述.class文件的

        4.java.lang.Class类也是有对象的,一个对象就代表着一个.class文件,只不过Class类的对象程序员无法自己创建,由JVM创建,但是程序员可以调对象,完成对应操作

File代表文件类无法获得成员变量/构造方法/成员方法,所以需要Class类

class 定义的关键字        Class 描述.class文件


反射的介绍

        .java源代码→javac编译.class文件→创建对象

        反射就是获取到堆内存中Class类型对象操作内存方法区的.class文件

        成员变量被封装成Field对象Field类就是用来描述成员变量的
        Class对象.getField()获取成员变量Field对象调用set/get方法

        成员方法被封装为Method对象Method类就是用来描述成员方法的
        Class对象.getMethod()获取成员方法对应的对象Method对象.invoke方法

        构造方法被封装了Constructor对象Constructor类就是用来描述构造方法的
        Class对象.getConstrucor()获取构造方法对应的对象

        构造方法对象.newInstance()执行构造方法,创建一个具体的对象出来

1.反射的第一步是什么?
        获取Class类对象,如此才可以解析类的全部成分


2.获取Class类的对象的三种方式
        方式一:Class c1 = Class.forName(“全类名”);
        方式二:Class c2 = 类名.class
        方式三:Class c3 = 对象.getClass();

    获取Class对象的方式
        方式一:
        java.lang.Object类,成员方法:
            public Class getClass(): 获取Class类型的对象

        方式二:
            任意类型(基本/引用),隐藏的class属性,获取该类对应的Class对象

        方式三:
            java.lang.Class类,静态方法:
            public static Class forName(String className)
                返回与带有给定字符串名的类或接口相关联的 Class 对象。
                参数:
                   String className: 类/接口 的全名称(包名+类/接口名)

       建议使用方式三:
            参数是String,可以写在配置文件中

        Class类的成员方法:
            public String getSimpleName(): 获得简单类名,只是类名,没有包
            public String getName(): 获取完整类名,包含包名+类名

public class Demo03GetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User();

        //public Class getClass(): 获取Class类型的对象
        Class c1 = user.getClass();

        //任意类型(基本/引用),隐藏的class属性,获取该类对应的Class对象
        Class c2 = User.class;

        //public static Class forName(String className)
        Class c3 = Class.forName("com.itheima.pojo.User");

        //class com.itheima.pojo.User
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);

        //任意一个类,只能被加载一次,所以对应的Class对象只有一个
        System.out.println(c1==c2);//true
        System.out.println(c1==c3);//true
        System.out.println(c2==c3);//true

        //基本类型也有对应的Class对象
        Class c4 = int.class;
        System.out.println(c4);
        System.out.println("-------------");

        //public String getName(): 获取完整类名,包含包名+类名
        String name = c1.getName();
        System.out.println(name);//com.itheima.pojo.User

        //public String getSimpleName(): 获得简单类名,只是类名,没有包
        String simpleName = c1.getSimpleName();
        System.out.println(simpleName);//User
    }
}

反射获取构造器对象

使用反射技术获取构造器对象并使用


反射的第一步是先得到类对象,然后从类对象中获取类的成分对象

Class类中用于获取构造器的方法


Constructor类中用于创建对象的方法

获取构造器的作用依然是初始化一个对象返回

1.利用反射技术获取构造器对象的方式?
        getDeclaredConstructors()
        getDeclaredConstructor (Class... parameterTypes)


2.反射得到的构造器可以做什么?
        依然是创建对象的
                public newInstance(Object... initargs)
        如果是非public的构造器,需要打开权限(暴力反射),然后再创建对象
                setAccessible(boolean)
                反射可以破坏封装性,私有的也可以执行了


反射获取成员变量对象

使用反射技术获取成员变量对象并使用


反射的第一步是先得到类对象,然后从类对象中获取类的成分对象

Class类中用于获取成员变量的方法

获取成员变量的作用依然是在某个对象中取值、赋值

1.利用反射技术获取成员变量的方式
        获取类中成员变量对象的方法
                getDeclaredFields()
                getDeclaredField (String name)
2.反射得到成员变量可以做什么?
        依然是在某个对象中取值和赋值。
                void set​(Object obj, Object value):
                Object get​(Object obj)
        如果某成员变量是非public的,需要打开权限(暴力反射),然后再取值、赋值
                setAccessible(boolean)


反射获取方法对象

        使用反射技术获取方法对象并使用

反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
Class类中用于获取成员方法的方法

获取成员方法的作用依然是在某个对象中进行执行此方法
Method类中用于触发执行的方法

1.利用反射技术获取成员方法对象的方式
        获取类中成员方法对象
                getDeclaredMethods()
                getDeclaredMethod (String name, Class... parameterTypes) 
2.反射得到成员方法可以做什么?
        依然是在某个对象中触发该方法执行。
                Object invoke​(Object obj, Object... args)
        如果某成员方法是非public的,需要打开权限(暴力反射),然后再触发执行
                setAccessible(boolean)

注释

        (Annotation)也叫元数据

概念:

        一种代码级别的说明,它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次

        它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释

作用:

     (1)编写文档:通过代码里标识的注解生成文档【例如,生成文档doc文档】
     (2)代码分析:通过代码里标识的注解对代码进行分析【例如,注解的反射】
     (3)编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【例如,Override】

常见注解:

      (1)@author:用来标识作者名
      (2)@version:用于标识对象的版本号,适用范围:文件、类、方法。
      (3)@Override:修饰方法声明,告诉编译器该方法是重写父类的方法,如果父类不存在该方法,编译失败。
      (4)@FunctionalInterface: 检测是否是函数式接口的

本质:

        注解本质上就是一个接口,该接口默认继承自Annotation接口

定义格式:

        public @interface 注解名称 {
                    属性类型 属性名() default 默认值 ;
        }


基本数据类型
String
Class
注解
枚举
以上类型的一维数组

特殊属性值value

        当注解中只有一个属性且名称是value,在使用注解时给value属性赋值可以直接给属性值,无论value是单值元素还是数组类型
        如果注解中除了value属性还有其他属性,且至少有一个属性没有默认值,则在使用注解给属性赋值时,value属性名不能省略


元注解

        元注解就是描述注解的注解

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988316.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号