1i javaWeb基础.txt
UP 返回
1.Junit白盒测试
步骤:
1 定义一个测试类:被测试的类名Test
2 定义测试方法:test测试的方法名
3 给方法加@Test
4 导入Junit依赖环境
一般用断言操作来处理结果:
public class CalculatorTest {
@Test
public void testAdd(){
//定义被测试类
Calculator c=new Calculator();
//调用被测试的方法
int result =c.add(1,2);
//断言
Assert.assertEquals(3,result);//前者是期望的结果,后者为实际结果
}
}
Before和After注解:
/**
* 初始化方法:
* 用于资源申请,所有测试方法在执行前都会先执行该方法
*/
@Before
public void init(){
}
/**
* 释放资源方法:
* 在所有测试方法在执行后都会自动执行该方法
*/
@After
public void close(){
}
2.反射(框架设计的灵魂)
1 将类的各个组成部分封装为其他对象,这就是反射机制
2 过程:
Source源代码阶段 Person.java → Person.class,仍然在磁盘上
↓
↓ 通过类加载器(ClassLoader)
↓
Class类对象,将类中的不同成员封装为对象 Class类对象阶段(加载进内存)
成员变量 Field[] fields
构造方法 Constructor[] cons
成员方法 Method[] methods
↓
↓ 通过类加载器(ClassLoader)
↓
Runtime运行时阶段 new Person()
3 好处
1 可以在程序运行过程中,操作这些对象
2 可以解耦,提高程序的可扩展性
4 Class对象功能
1 获取成员变量们
Field[] getFields() 获取所有public修饰的成员变量
Field getField(String name) 获取指定名称的public变量
Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name) 获取任意指定名称的变量
Field的方法:
Field a=personClass.getField("name");
Person p=new Person();
Object value=a.get(p);//获取变量值 !!!!!!!!!!!!!!!!
a.set(p,"张三");//设置变量值 !!!!!!!!!!!!!!!!
Field age=personClass.getDeclaredField("age");
//忽略访问权限修饰符的安全检查
age.setAccessible(true);//暴力反射 !!!!!!!!!!!!
Object value2=age.get(p);
System.out.println(value2);
2 获取构造方法
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(类<?>...parameterTypes)
Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
Constructor<T>[] getDeclaredConstructors()
Constructor:构造方法
Constructor constructor1=personClass.getConstructor(String.class,int.class);
Object person1=constructor1.newInstance("张三",25);//用来创建对象
Constructor constructor2=personClass.getConstructor();
Object person2=constructor2.newInstance();
person2=personClass.newInstance();//如果使用空参数构造方法创建对象,可以简化操作,直接使用Class对象的newInstance
constructor1.setAccessible(true);//同样可以暴力反射
3 获取成员方法们
Method[] getMethods()
Method getMethod(String name,类<?>... parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?>... parameterTypes)
Method:方法对象
Method eatMethod=personClass.getMethod("eat");
p = new Person();
eatMethod.invoke(p);//执行方法
Method eatMethod2=personClass.getMethod("eat",String.class);
eatMethod.invoke(p,"饭");
Method[] methods=personClass.getMethods();//获取所有public方法
for(Method method:methods){
String name=method.getName();//获取方法名
}
4 获取类名
String getName()
5 利用反射读取配置文件(框架测试)
public class ReflectTest {
public static void main(String[] args) throws Exception{
//1.加载配置文件
//1.1 创建Properties对象
Properties pro=new Properties();
//1.2 加载配置文件,转换为一个集合
//1.2.1 获取class目录下的配置文件
ClassLoader classLoader=ReflectTest.class.getClassLoader();
InputStream is=classLoader.getResourceAsStream("pro.properties");
pro.load(is);
//2.获取配置文件中定义的数据
String className=pro.getProperty("className");
String methodName=pro.getProperty("methodName");
//3.加载该类进内存
Class cls=Class.forName(className);
//4.创建对象
Object obj=cls.newInstance();
//5.获取方法对象
Method method=cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
}
6 获取Class对象的方式(分别对应三种不同的状态)
1 Class.forName("全类名"):将字节码文件加载进内存,返回class对象
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
2 类名.class:通过类名的属性class获取
多用于参数的传递
3 对象.getClass():getClass()方法在Object类中定义了
多用于对象的获取字节码的方式
Class cls1=Class.forName("cn.domain.Person");
Class cls2=Person.class;
Class cls3=p.getClass();
结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
3.注解
1 作用
编写文档:通过代码里标识的注解生成文档【生成doc文档 】 在cmd中使用javadoc AnnoDemo1.java 命令生成文档
代码分析:对待吗进行分析【使用反射】
编译检查:让编译器能够实现基本的编译检查【Override】
2 jdk预定义的一些注解
@Override:检测被该注解标注的方法是否是继承自父类(接口)的
@Deprecated:该注解标注的内容已过时 //仍可调用,但调用时方法会被加横线
@SuppressWarnings:压制警告 //可以写在方法上,但一般写在类上,@SuppressWarnings("all"),表示让编译器忽略一切警告
3 自定义注解
1 格式:
元注解
public @interface 注解名称{
属性列表
}
2 本质:注解本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation{}
3 属性:接口中的抽象方法
要求:
1 属性的返回值类型:基本数据类型,String,枚举,注解,以上类型的数组 //不可以是void或者类
2 定义了属性,在使用时需要给属性赋值。如果定义属性时使用了default关键字给属性默认值,则使用注解时可不赋值
如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
3 数组赋值时,值使用{}包裹;如果数组只有一个值,则大括号可以省略
@MyAnno(value=12,per=Per.P1,anno2=@MyAnno2,strs={"abc",""})
4 元注解:用于描述注解的注解
@Target:描述注解能够作用的位置 @Target(value={ElementType.TYPE,ElementType.METHOD})
ElementType取值:
TYPE:可以作用于类上
METHOD:可以作用于方法上
FIELD:可以作用于子成员变量上
@Retention:描述注解被保留的阶段 @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,或保留到class字节码文件中,并被JVM读取到。一般自定义的注解都取这个值
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承
4 在程序使用(解析)注解:获取注解中定义的属性值
1 获取注解定义的位置的对象(Class,Method,Field)
2 获取指定的注解 getAnnotation(Class)
3 调用注解中的抽象方法获取配置的属性值
@Pro(className = "cn.domain.Demo1",methodName = "show") //Pro是自定义的注解,里面有两个属性方法
public class ReflectAnnoTest {
public static void main(String[] args) throws Exception{
//1 解析注解
//1.1 获取该类的字节码文件对象
Class<ReflectAnnoTest> reflectAnnoTestClass=ReflectAnnoTest.class;
//2 获取上面的注解对象
//其实就是在内存中生成了一个该注解接口的子类实现对象
Pro an=reflectAnnoTestClass.getAnnotation(Pro.class);
//3 调用注解对象中定义的抽象方法,获取返回值
String className=an.className(); //会自动返回注解赋值时给的值,下同
String methodName=an.methodName();
//后面的操作同上面反射一样
}
}
DOWN 返回