一、单元测试
使用Junit框架
二、反射
反射可以破坏封装性,得到一个类的所有成分,最重要的途径是用来参与Java框架制作。
获取Class对象的三种方式
- Class c1 = 类名.class
- 调用Class提供方法: public static Class forName(String package);
- Object提供的方法: public Class getClass(); Class c3 = 对象.getClass();
反射案例
需求:对于任意对象,将对象的字段名和对应的值保存到文件中去
假设我们有Teacher类和Student类,那么代码如下
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Demo01 { private String dirPath = "src/main/resources/P13/";
@Test public void test01() { Student s1 = new Student("淇",22,'女',167.56,"swim"); Teacher t1 = new Teacher("柳",5433.2);
work(s1, dirPath+"s.txt"); work(t1, dirPath+"t.txt"); }
public void work(Object object, String filePath) { //1.create fileIO try ( // FileWriter fileWriter = new FileWriter(filePath); PrintWriter printWriter = new PrintWriter(filePath); ) { //2.get Object fields info Class c = object.getClass(); Field[] declaredFields = c.getDeclaredFields(); printWriter.println("--------"+c.getSimpleName()+"--------"); for (Field f : declaredFields) { f.setAccessible(true); printWriter.println(f.getName()+" --> "+f.get(object)); } } catch (Exception e) { throw new RuntimeException(e); } } }
|
三、注解
我的注解一如下
language-java1 2 3 4 5 6 7
| public @interface MyAnnotation { String aaa(); boolean bbb() default true; String[] ccc(); }
|
注解二如下
language-java1 2 3 4
| public @interface MyAnnotation2 { String value(); }
|
注解使用如下
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package org.kmo.d08_Annotation.Test01;
import org.junit.Test;
@MyAnnotation(aaa="牛魔王", ccc={ "Python","Java"}) public class MyTest01 { @MyAnnotation(aaa="铁山",bbb=false,ccc={ "C++","C"}) public void test1(){ }
@MyAnnotation2("孙悟空") public void test2(){ } }
|
解析注解案例
需求:
定义注解MyTest4。
定义一个Demo类,在类中定义一个test1方法,并在该类和其方法上使用MyTest4注解。
定义AnnotationTest3测试类,解析Demo类中的全部注解。
这是一个注解
language-java1 2 3 4 5 6 7 8 9
| @Target({ ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyTest4 { String value(); double aaa() default 100; String[] bbb(); }
|
这是Demo类
language-java1 2 3 4 5 6 7 8 9 10 11 12
| @MyTest4(value = "vv",aaa = 99.9, bbb={ "b","bb","bbb"}) public class Demo {
@MyTest4(value = "我是至尊宝",aaa = 100.9, bbb = { "小淇","爱你"}) public void test01(){
} }
|
这是解析类,解析Demo类上的注解以及Demo类方法的注解
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class AnnotationTest3 {
@Test public void test01(){ Class c = Demo.class; if (c.isAnnotationPresent(MyTest4.class)){ MyTest4 myTest4 = (MyTest4) c.getDeclaredAnnotation(MyTest4.class); System.out.println(myTest4.value()); System.out.println(myTest4.aaa()); System.out.println(Arrays.toString(myTest4.bbb())); } } @Test public void test02() throws Exception { Class c = Demo.class; Method method = c.getDeclaredMethod("test01"); if (method.isAnnotationPresent(MyTest4.class)){ MyTest4 myTest4 = (MyTest4) method.getDeclaredAnnotation(MyTest4.class); System.out.println(myTest4.value()); System.out.println(myTest4.aaa()); System.out.println(Arrays.toString(myTest4.bbb())); } } }
|
注解案例-简易Junit
这是一个注解
language-java1 2 3 4 5 6
| @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyTest {
}
|
这是运行代码
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Demo { @MyTest() public void test01(){ System.out.println("===Test01===="); }
public void test02(){ System.out.println("===Test02===="); }
@MyTest public void test03(){ System.out.println("===Test03===="); } public void test04(){ System.out.println("===Test04===="); }
public static void main(String[] args) throws Exception { Demo demo = new Demo(); Class c = Demo.class; Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(MyTest.class)){ method.invoke(demo); } } } }
|
四、动态代理
相当于把相同的地方集合到一起了,只要写一遍,且灵活。
动态代理案例
需求:对一个类的所有方法前后都加上计时,当类的方法被调用时,输出时间。
一个UserService接口
language-java1 2 3 4 5 6
| public interface UserService { void login(String loginName, String password) throws Exception; void deleteUsers() throws Exception; String[] selectUsers() throws Exception; }
|
UserServicelmpl实现类
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class UserServiceImpl implements UserService { @Override public void login(String loginName, String passWord) throws Exception { if ("admin".equals(loginName) && "123456".equals(passWord)) { System.out.println("您登录成功,欢迎光临本系统~"); } else { System.out.println("您登录失败,用户名或密码错误~"); } Thread.sleep(1000); }
@Override public void deleteUsers() throws Exception { System.out.println("成功删除了1万个用户~"); Thread.sleep(1500); }
@Override public String[] selectUsers() throws Exception { System.out.println("查询出3个用户"); String[] names = { "张全蛋","李二狗","牛爱花"}; Thread.sleep(500); return names; } }
|
ProxyUtil代理类
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class ProxyUtil { public static UserService createProxy(UserService userService){ UserService userServiceProxy = (UserService) Proxy.newProxyInstance( ProxyUtil.class.getClassLoader(), new Class[]{ UserService.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("login") || method.getName().equals("deleteUsers") || method.getName().equals("selectUsers")){ long startTime = System.currentTimeMillis(); Object res = method.invoke(userService, args); long endTime = System.currentTimeMillis(); System.out.println(method.getName()+"方法执行耗时: " + (endTime - startTime) / 1000.0 + "s"); return res; }else { Object res = method.invoke(userService, args); return res; } } } );
return userServiceProxy; } }
|
在这个代理中,被代理的类传入,Proxy.newProxyInstance中重写的invoke方法里,就是在重写被代理类的所有方法,可以理解为在调用(被代理的)类的方法时,其实是在调用这里的invoke。如果不想做更改,直接执行method.invoke就行。
运行代码
language-java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Tests { public static void main(String[] args) throws Exception { // UserService userService = new UserServiceImpl(); UserService userService = ProxyUtil.createProxy(new UserServiceImpl());
userService.login("admin","123456"); System.out.println("--------------------"); userService.deleteUsers(); System.out.println("--------------------"); String[] strings = userService.selectUsers(); System.out.println(Arrays.toString(strings)); System.out.println("--------------------");
} }
|