Junit、反射、注解、相关知识点更新中

Junit单元测试

测试分类

	黑盒测试:
		不需要书写代码,刚给输入值,看程序是否能够输出期望的值;
	白盒测试:
		需要写代码的,关注程序具体的执行流程.

白盒测试

步骤:

定义一个测试类(测试用例)
	建议:
		测试类名:被测试的类型Test		例如CalculatorTest
		包名:xxx.xxx.xx.Test		cn.it.test
		
定义测试方法:可以独立运行
	建议:
		方法名:test测试的方法名		testAdd()
		返回值:void
		参数列表:空参
给方法加上注解:@Test
	不需要main方法,也可以独立运行一个或者多个方法测试
导入JUnit依赖环境

判定结果

红色:失败
绿色:成功
一般我们会使用断言来操作处理结果
Assert.assertEquals(3,result);		
	第一值时表示我预计结果是3,result是实际返回值,
	如果预计结果和实际结果相同,会绿色否则红色;

补充

@Before:
	修饰的方法会在测试方法执行之前被自动执行;
@After
	修饰的方法会在测试方法执行之后被自动执行

反射:框架设计的灵魂

框架:半成品软件.可以在框架的基础上进行软件开发,简化编码

反射:将类的各个组成部分封装为其他对象,这就是反射机制

	将成员变量封装成	Field[] fields数组
	将构造方法封装成	 Constructor[] cons数组		[坑死chua科特]
	将成员方法封装成	Method[] methods数组

好处:
	可以在程序运行过程中,操作这些对象
	可以解耦,提高程序的可扩展性.

获取Class对象的方式:

1.Class.forname("全类名"):		将字节码文件加载进内存,返回Class对象
(多用于配置文件,将类名定义在配置文件中.读取文件,加载类)
	Class cls1=Class.forName("cn.it.domain.Person");
	System.out.println(cls1);


2.类名.class:					通过类名的属性class获取
(多用于参数的传递)
	Class cls2 = Person.class; 
	System.out.println(cls2);


3.对象.getClass():				getClass()方法在Object类中定义着
(多用于对象的获取字节码的方式)
	Person p=new Person(); 
	Class cls3=p.getClass(); 
	System.out.println(cls3);

结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,
不论通过哪一种方式获取的Class对象都是同一个;

Class对象功能

 //获取Person的Class对象
  Class presonClass = Preson.class;

1获取成员变你们
	获取所有public修饰的变量
		* Field[] getFields()
	获取指定名称的 public修饰的成员变量
		* Field getfield(string name)
	获取所有成员变量,不考虑修饰符
		* Field[] getDeclaredFields()
	获取指定名称的成员变量,不考虑修饰符
		* Field getDeclaredField(string name)
2.获取构造方法们
	* Constructor<?>[] getconstructors()
	* Constructor<T> getconstructor(<?>... parameterTypes)
	* 
	* Constructor<t> getDeclaredConstructor(<?>... parametertypes) 
	* Constructor<?>[] getDeclaredConstructors()
3.获取成员方法们:
	* Method[] getMethods()
	* Method getMethod(string name,<?>... parameterTypes)
	* 
	* Method[] getDeclaredMethods()
	*Method getDeclaredMethod(string name,<?>... parameterTypes)
4.获取类名
	* string[getName()

Field:成员变量

操作:
	设置值
		void set(Object obj,Object value)
	获取值
		get (Object obj)
	忽略访问权限修饰符的安全检查
		setAccessible(true);	//暴力反射

Constructor:构造方法

创建对象:
	T newInstance(object... initargs)
	如果使用空参数构造方法创建对象,操作可以简化:class对象的newInstance方法

Method:方法对象
	执行方法卡
		object invoke(object obj, object... args)
	获取方法名称:
		string getName:获取方法名

案例:

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        /*1 获取成员变量们
                * Field[]getFields()    //获取所有public修饰的成员变量;
                * Field getfield(string name)//获取指定名称的 public修饰的成员变量
                    忽略访问权限修饰符的安全检查
			        setAccessible(true);	//暴力反射
                * Field[]getDeclaredFields()//获取所有成员变量,不考虑修饰符
                * Field getDeclaredField(string name)//获取指定名称的成员变量,不考虑修饰符
        2. 获取构造方法们
                * Constructor < ?>[]getconstructors()
                * Constructor < T > getconstructor(类 < ? >...parameterTypes)

	            *Constructor<t> getDeclaredConstructor (类 < ? >...parametertypes)
	            *Constructor<?>[] getDeclaredConstructors ()
        3. 获取成员方法们:
	            *Method[] getMethods ()
                * Method getMethod(string name, 类 < ? >...parameterTypes)
	*
	            *Method[] getDeclaredMethods ()
                * Method getDeclaredMethod(string name, 类 < ? >...parameterTypes)
        4. 获取类名
                * string[getName()
    */


        //获取Person的Class对象
        Class presonClass = Preson.class;
        //Field[] getField()获取所有public修饰的变量
        Field[] fields = presonClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-------");


        // Field getfield(string name)
        Field a = presonClass.getField("a");
        //获取成员变量a的值
        Preson p=new Preson();
        Object value = a.get(p);
        System.out.println(value);

        //设置"a"的值
        a.set(p,"张三");
        System.out.println(p);
        System.out.println("=========");

        //Field[] getDeclaredFields():获取所有成员变量,不考虑修饰符
        Field[] declaredFields = presonClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        Field d = presonClass.getDeclaredField("d");//d为私有成员变量
        //忽略访问权限修饰符的安全检查
        d.setAccessible(true);//暴力反射
        Object value2 = d.get(p);
        System.out.println(value2);
        System.out.println("+++++++++");


        //获取一个构造器对象constructor
        Constructor constructor = presonClass.getConstructor(String.class,int.class);//Preson构造方法中传递的参数类型
        System.out.println(constructor);
        //创建对象
        Object preson = constructor.newInstance("李四", 30);
        System.out.println(preson);
        System.out.println("--------------------");


        //获取一个构造器对象constructor---空参构造方法
        Constructor constructor1 = presonClass.getConstructor();//Preson构造方法中传递的参数类型
        System.out.println(constructor1);
        //创建对象
        Object preson1 = constructor1.newInstance();
        System.out.println(preson1);

        //获取一个构造器对象constructor---空参构造方法--简化
        Object o = presonClass.newInstance();
        System.out.println(o);

        //也有暴力反射
        constructor1.setAccessible(true);




        //获取指定名称的方法
        Method eat = presonClass.getMethod("eat");
        Preson p1=new Preson();
        //执行方法
        eat.invoke(p1);

        //获取指定名称的带参方法
        Method eat1 = presonClass.getMethod("eat", String.class);
        eat1.invoke(p1,"饭");

        //获取所有public修饰的方法
        Method[] methods = presonClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //获取类名
        String className = presonClass.getName();
        System.out.println(className);
    }


案例需求:

写一个框架,不改变该类的任何代码,可以创建任意类的对象,可以执行任意方法

   public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        //加载配置文件
        //创建Properties对象
        Properties pro=new Properties();
        //获取class目录下的配置文件
        InputStream is = Preson_Test.class.getClassLoader().getResourceAsStream("pro.properties");

        pro.load(is);
        //获取配置文件中定义的数据
        String classname = pro.getProperty("classname");
        String methodName = pro.getProperty("methodName");
		//加载该类进内存
        Class aClass = Class.forName(classname);
        //使用获取空参构造方法简化来获取放方法对象
        Object o = aClass.newInstance();
        //获取指定名称的方法
        Method method = aClass.getMethod(methodName);
        //执行方法
        method.invoke(o);
    }

pro.properties文件

classname=ClassTest.Preson
methodName=eat

注解

 概念:说明程序的。 给计算机看的 
注释:用文字描述程序的。给程序员看的

*定义:注解(Annotation)也叫元数据。一种代码级别的说明了它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

作用分类:
	①编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
	②代码分析:通过代码里标识的注解对代码进行分析【使用反射】
	③编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【override】

JDK中预定义的一些注解

@Override :检测被该注解标注的方法是否是继承自父类(接口)的
@Deprecated:该注解标注的内容,表示已过时
@suppressWarnings:压制警告
	一般传递参数all @SuppressWarnings("all")

自定义注解

格式:
	元注解
	public @interface 注解名称{}
	
本质:注解本质上就是一个接口,该接口默认继承Annotation接口
	* public interface MyAnno extends java.lang.annotation.Annotation {}
	
属性:接口中的抽象方法
	*要求:
		1.属性的返回值类型
			基本数据类型 
				String
				枚举
				注解
				以上类型的数组
				
		2.定义了属性,在使用时需要给属性赋值
		
			1 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,
			可以不进行属性的赋值。
			
			2.如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,
			直接定义值即可。
			
			3.数组赋值时,值使用{包裹。如果数组中只有一个值,则{}省略

元注解:用于描述注解的注解

* @Target:描述注解能够作用的位置
	ElementType取值:
		TYPE:可以作用于类上
		METHOD:可以作用于方法上
		FIELD:可以作用于成员变量上
@Retention:描述注解被保留的阶段
	@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承

在程序使用(解析)注解:获取注解中定义的属性值

	1.获取注解定义的位置的对象 (classMethod,Field) 
	2.获取指定的注解
		getAnnotation(Class)
		//其实就是在内存中生成了一个该注解接口的子类实现对象
	
				public class ProImpl implements Pro{
					public string className(){
						return "cn.itcast.annotation.Demo1";
						}
						public string methodName(){
							return "show";
						}
				}
	3.调用注解中的抽象方法获取配置的属性值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值