学习笔记-JavaSE(3)

单元测试

黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值

白盒测试:需要写代码.关注程序具体的执行过程

Junit测试:白盒测试

步骤:

  1. 定义一个测试类(测试用例)

    建议:

    测试类名:被测试类名Test

    包名:xxx.xx.xx.test

  2. 定义测试方法:可独立运行

    建议:

    方法名:test测试方法名

    返回值:void

    参数列表:空参数

  3. 给方法加 @Test

  4. 导入Junit的依赖

断言:Assert.function(except,res)

public class ClassNameTest{
    // 所有测试方法执行前都会执行该方法
    @Before
    public void init(){}
    // 所有测试方法执行玩都会执行该方法
    @After
    public void close(){}
    @Test
    public void test1(){}
    @Test
    public void test2(){}
}

反射

框架设计的灵魂

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

反射: 将类的各个组成部分封装为其他对象

​ 好处:

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

获取Class对象的方式:

1. Class.forName("全类民"): 从字节码加载到内存,返回对象  (编译后)
  	1. 多用于配置文件,将类名定义在配置文件中.读取文件,加载类
2. 类名.class : 通过类名的属性class获取 (加载完成后)
  	1. 多用于参数传递
3. 对象.getClass() : 使用Object类的getClass方法 (创建对象后)
  	1. 多用于对象获取字节码

结论:

​ 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次.

class对象功能

获取功能:

  1. 获取成员变量们

    1. Field[] getFields()
    2. Field getField(String name)
    3. Field[] getDeclaredFields()
    4. Field getDeclaredFields(String name)
    package demo2.reflect;
    
    import demo2.domain.Person;
    
    import java.lang.reflect.Field;
    
    public class ReflectDemo1 {
        /**
         获取Class对象的方式:
         1. Class.forName("全类民"): 从字节码加载到内存,返回对象  (编译后)
         2. 类名.class : 通过类名的属性class获取 (加载完成后)
         3. 对象.getClass() : 使用Object类的getClass方法 (创建对象后)
         */
        public static void main(String[] args) throws Exception {
            // 0.获取Person的Class对象
            Class<Person> personClass = Person.class;
            // 1.获取所有 Public 的成员变量
            Field[] fields = personClass.getFields();
            for (Field field : fields) {
                System.out.println(field);//public java.lang.String demo2.domain.Person.a
            }
            System.out.println("-----------");
            // 2.获取名字为 a 的 Public 的成员变量
            Field a = personClass.getField("a");
    
            Person person = new Person();
            // 3.获取 a 变量的值
            Object o = a.get(person);
            System.out.println(o);//null
            // 4.设置 a 变量的值
            a.set(person,"a3");
            System.out.println(person);//Person{name='null', age=null, a='a3', b='null', c='null', d='null'}
    
            // 1. 获取所有 成员变量
            Field[] declaredFields = personClass.getDeclaredFields();
            for (Field field : declaredFields) {
                System.out.println(field);
            }
            // 2. 获取指定名字的 成员变量
            Field d = personClass.getDeclaredField("d");
            // 3. 获取 私有变量 d 的值
            // d.get(person); // 报错
            // 如果设置或访问私有变量,需要暴力反射
            d.setAccessible(true);
            Object o1 = d.get(person);
            System.out.println(o1);
            // 4. 设置 变量的值同上
            d.set(person,"d3");
            System.out.println(person);//Person{name='null', age=null, a='a3', b='null', c='null', d='d3'}
        }
    }
    
    
  2. 获取构造方法们

    1. 类似
  3. 获取成员方法们

    1. 类似
  4. 获取类名:getName()

构造方法返回的Constructor 方法:

class Constructor 
	// 创建对象
	T newInstance(Object... initargs)
    // 创建空参对象也可使用
    ClassObject.newInstance()

需求:写一个框架,不能改变该类的任何代码,可以创建任意类的对象,并且执行其中任意方法

实现:

1. 配置文件
2. 反射
package demo2.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Properties properties = new Properties();

        ClassLoader classLoader = ReflectDemo.class.getClassLoader();
        InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
        
        properties.load(resourceAsStream);
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        // 获取 class对象
        Class aClass = Class.forName(className);
        // 获取 方法
        Method method = aClass.getMethod(methodName);
        // 创建实例对象
        Object o = aClass.newInstance();
        method.invoke(o);
    }
}

注解

注释:用文字描述程序,给程序员看的

概念: 说明程序,给计算机看的

概念描述:

1. jdk1.5之后的特性
2. 说明程序的
3. 使用注解: `@注解名称`

作用分类:

  1. 编写文档: 生成javadoc文档
  2. 代码分析
  3. 编译检查: 例如:@Override

JDK中预定义的一些注解

@Override 检测被注解的方法是否继承自父类

@Deprecated 该注解标注的内容,表示已过时

@SuppressWarnings 压制警告

​ - 一般传递参数"all" @SupperssWarnings("all")

自定义注解

格式:

元注解
public @interface 注解名称{
}

本质: 注解本质就是一个接口,该接口默认继承Annocation接口

public interface annocationname extends java.lang.annotation.Annotation{}

属性:接口中的抽象方法

1. 要求属性的返回值类型:
  	1. 基本数据类型
  	2. String
  	3. 枚举
  	4. 注解
  	5. 以上类型的数组
2. 定义的属性在使用是需要被赋值
  	1. 如果定义属性时,使用default关键字给属性赋默认值
  	2. 如果只有一个属性,属性名为value,则可以直接写值
  	3. 数组赋值时,值使用{}包裹,如果只有一个值,{}可省略
  	4. 注解类型赋值使用@注解名

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

@Target: 描述注解能够作用的位置

属性为ElementType[] value

ElemenType为枚举:

TYPE 类

METHOD 方法

FIELD 变量

@Retention: 描述注解被保留的阶段

属性为RententionPolicy value

RententionPolicy为枚举:

RUNTIME 保留到class字节码文件中,并被jvm读取到

@Documented:描述注解是否被抽取到api文档中

@:描述注解是否能被继承

使用注解(获取注解中定义的值)

  1. 使用注解取代配置文件来配置程序

  2. 测试框架

小结:

  1. 以后大多数时候,我们都会使用注解,而不是自定义注解
  2. 注解给编译器用,给解析程序用
  3. 注解不是程序的一部分,可以理解为一个标签
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值