本人是一个在读学生,本科二年纪。本人跟随黑马程序员Java Web的B站视频去学习。
在此,我将知识点、笔记和案例总结起来,希望学习Web前端的小伙伴可以拿去学习。
总结第一节导论笔记:
----------
# 今日内容
1. Junit单元测试
2. 反射
3. 注解
## Junit单元测试:
* 测试分类:
1. 黑盒测试:不需要写代码,给输入值,看程序是否输出期望的值。
2. 白盒测试:需要写的代码,关注代码具体的执行流程。
* Junit使用:白盒测试
* 步骤
1. 定义一个测试类(测试用例)
* 测试类名:被测试类名Test
* 包名:xxx.xxx.xx.test cn.itcast.test
2. 定义测试方法:可以独立运行
* 方法名:test测试的方法名 testAdd()
* 返回值:void
* 参数列表:空参
3. 给方法加@Test
4. 到入Junit依赖环境
* 结果
* 红色:失败
* 绿色:成功
* 一般会使用断言操作处理结果
* Assert.assertEqual(期望的结果,运算的结果);
* 补充:
* @Befoere
* 修饰的方法会在测试方法之前自动执行
* @After
* 修饰的方法会在测试方法之后自动执行
(无论测试方法中有无错误,都会执行这两个方法)
## 反射:框架知识的灵魂
* 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码。
* 发射:将类的各个组成部分封装为其他对象,这就是反射机制。
* 好处:
1. 可以在程序运行过程中,操作这些对象。
2. 可以解耦,提高程序的可扩展性。
* 获取Class对象的方式:
1. Class.forName("全类名"):将字节码文件加载进内存,返回Calss对象。
* 多用于配置文件,将类定义在配置文件中。读取文件,加载类。
2. 类名.class:通过类名的属性class获取
* 多用于参数的传递。
3. 对象.getClass():getClass()方法在Object类中定义的。
* 多用于对象的获取字节码的方式。
* 结论:
同一个字节码文件(*.class)在一次程序运行的过程中,只会加载一次,不论通过哪一种方式获取的Class对象都是同一个。
* Class对象功能:
* 获取功能:
1. 获取成员变量们
* Field[] getFields() :获取所有public修饰的成员变量
* Field getField(String name) :获取指定名称public修饰的成员变量
* Field[] getDeclaredFields() :获取所有的成员变量,不考虑修饰符。
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
3. 获取成员方法们
* Method[] getMethods()
* method getMethod(String name,类<?>...parameterType)
* Method[] getDeclaredMethods()
* method getDeclaredMethod(String name,类<?>...parameterType)
4. 获取类名
* String getName()
* Field:成员变量
* 操作:
1. 设置值
* void set(Object obj,Object value)
2. 获取值
* get(Object obj)
3. 忽略访问权限修饰符的安全检查(当使用Declared..)
* setAccessible(true);暴力反射
* Constructor:构造方法
* 创建对象
* T newInstance(object...initargs) 例如:Object personObject = constructor.newInstance("扎根三",22);
* 如果使用空参构造方法创建对象,操作可简化为:Class对象的newInstance方法
* Method:方法对象
* 执行方法:
* Object invoke(Objecct obj:方法对象的名称,Object... args:方法实际参数列表)
例如:java.lang.reflect.Method eat_method2 = personClass.getMethod("eatfood", String.class);-------public void eatfood(String food) {}
* 获取方法名
* String getName:获取方法名
* 获取类目:String string = 类名.getName()
* 案例:
* 需求:写一个"框架",不能改变该类的任意代码的前提下,可以帮助我们创建任意类的对象,并且执行其中任意方法。
* 实现:
1. 配置文件
2. 反射
* 步骤
1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2. 在程序中加载读取配置文件
3. 使用反射技术加载文件进入内存
4. 创建对象
5. 执行方法
## 注解
* 注解概念:说明程序。给计算机看的。JDK1.5版本
* 注释概念:用文字去描述程序的。给程序员看。
* 概念描述:
* JDK1.5之后新特性
* 说明程序
* 使用注解方法:
* @注解名称
* 作用分类:
* 编译检查:
* 编写文档:
* 代码分析:主要
* JDK中预定义的一些注解
* @Override:检测被该注解标注的方法是否是继承自父类(接口)的
* @Deprecated:该注解标注的内容,表示已过时
* @SuppressWarning:压制警告
* 一般形式----@SuppressWarnings("all")
* 自定义注解
* 格式:
* 元注解:public @interfa 注解名{
属性列表
}
* 本质:注解本质上就是一个接口,该接口默认继承Amotation接口
* public interfa 注解名 extends java.lang.annotation.Amotation{}
* 注解属性:接口中可以定义的内容(接口中可以定义的抽象方法(方法声明))
* 要求:
1. 属性的返回值类型
* 基本数据类型
* 字符串String
* 枚举
* 注解
* 以上类型的数组
2. 定义了属性,在使用时需要给属性赋值
* 在定义时,将注解的属性定义为类似于属性的。例如int age();
* 使用注解是可用 @MyAnno(age = 1,name = "张三")
* 若不想在注解中赋值,例如@MyAnno(age = 1,name = "张三"),可以在自定义注解时属性设为: String name() default "张三";
* 若只有一个属性需要赋值,并且属性的值时value,则value可以省略,直接定义即可。
* 枚举类型赋值:@MyAnno(preson(自定义注解中的枚举对象名称) = Person(枚举名称).P1(定义在枚举中的P1,P2))
* 注解类型赋值: 自定义注解当中有:MyAnno2 myAnno2();
赋值为@MyAnno(myAnno2 = @MyAnno2)
* 数组类型赋值:值使用{}包裹,当数组中只有一个值,则{}可省略。
例如:string = {"aaa","bbb"}、string = "aaa"
*元注解:用于描述注解的注解
1. @Target:描述注解作用的位置
* ElementType取值:
1. TYPE:作用于类上
2. METHOD:作用于方法上
3. FIELLD:作用于成员变量上
2. @Retention:描述注解被保留的阶段
* @Retention(@RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中并被JVM读取到
3. @Documented:描述注解是否被抽到api文档中
4. @Inherited:描述注解是否被子类继承
* 在程序中使用(解析)注解:获取注解中定义的属性值
1. 获取注解定义的位置的对象(calss/method/field)
2. 获取指定的注解
* getAnnotation(Class)
3. 调用注解中抽象方法来获取配置的属性值
* 小结:
1. 以后大多数时候,我们会使用注解,而不是自定义注解
2. 注解给谁用:
1. 编译器
2. 给解析程序用
3. 注解不是程序的一部分,可以理解为注解就是一个标签。
下面是用到的案例,希望可以帮助到大家。
package reflect;
import java.io.File;
import com.sun.jdi.Field;
import domain.Person;
public class ReflectDemo2 {
/*
1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
3. 获取成员方法们
* Method[] getMethods()
* method getMethod(String name,类<?>...parameterType)
* Method[] getDeclaredMethods()
* method getDeclaredMethod(String name,类<?>...parameterType)
4. 获取类名
* String getName()
*/
public static void main(String[] args) throws Exception{
//0.获取Person的Class对象
Class personClass = Person.class;
/*
* 1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
*/
//1.Field[] getFields()
java.lang.reflect.Field[] fields = personClass.getFields();
for(java.lang.reflect.Field field : fields) {
System.out.println(field);
}
System.out.println("888888888888888888888888888888888888");
//2.Field getField(String name)
java.lang.reflect.Field a = personClass.getField("a");
//获取成员变量的值
Person person = new Person();
Object valueObject = a.get(person);
System.out.println(valueObject);
//设置成员变量的值
a.set(person, "张三");
System.out.println(person);
System.out.println("888888888888888888888888888888888888");
//3.Field[] getDeclaredFields()
java.lang.reflect.Field[] declaredFields = personClass.getDeclaredFields();
for(java.lang.reflect.Field declaredField :declaredFields) {
System.out.println(declaredField);
}
System.out.println("888888888888888888888888888888888888");
//4.Field getDeclaredField(String name)
java.lang.reflect.Field dField = personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查
dField.setAccessible(true);//暴力反射
Object value2 = dField.get(person);
System.out.println(value2);
}
}package reflect;
import java.io.File;
import java.lang.reflect.Constructor;
import java.rmi.server.ObjID;
import com.sun.jdi.Field;
import domain.Person;
public class ReflectDemo3 {
/*
1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
3. 获取成员方法们
* Method[] getMethods()
* method getMethod(String name,类<?>...parameterType)
* Method[] getDeclaredMethods()
* method getDeclaredMethod(String name,类<?>...parameterType)
4. 获取类名
* String getName()
*/
public static void main(String[] args) throws Exception{
//0.获取Person的Class对象
Class personClass = Person.class;
/*
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
*/
//1.Constructor<T> getConstructor(类<?>...parameterTypes)
Constructor constructor = personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象--赋值--有参
Object personObject = constructor.newInstance("扎根三",22);
System.out.println(personObject);
//创建对象--赋值--无参
Object w = personClass.newInstance();
System.out.println(w);
}
}package reflect;
import java.lang.reflect.Constructor;
import java.rmi.server.ObjID;
import com.sun.jdi.Field;
import com.sun.jdi.Method;
import domain.Person;
public class ReflectDemo4 {
/*
1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>...parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
* Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
3. 获取成员方法们
* Method[] getMethods()
* method getMethod(String name,类<?>...parameterType)
* Method[] getDeclaredMethods()
* method getDeclaredMethod(String name,类<?>...parameterType)
4. 获取类名
* String getName()
*/
public static void main(String[] args) throws Exception{
//0.获取Person的Class对象
Class personClass = Person.class;
/*
3. 获取成员方法们
* Method[] getMethods()
* method getMethod(String name,类<?>...parameterType)
* Method[] getDeclaredMethods()
* method getDeclaredMethod(String name,类<?>...parameterType)
*/
//获取指定名称的方法---无参数
java.lang.reflect.Method eat_method = personClass.getMethod("eat");
Person person = new Person();
//执行方法
eat_method.invoke(person, null);
//获取指定名称的方法---有参数
java.lang.reflect.Method eat_method2 = personClass.getMethod("eatfood", String.class);
Person person2 = new Person();
//执行方法
eat_method2.invoke(person2, "吃饭");
//获取所有public修饰的方法
java.lang.reflect.Method[] methods = personClass.getMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i]);
}
System.out.println("*******************************");
for(java.lang.reflect.Method method : methods) {
System.out.println(method);
String nameString = method.getName();
System.out.println(nameString);
}
//获取类目
String nameClassString = personClass.getName();
System.out.println(nameClassString);
}
}