JavaSE-高级特性

JavaSE-高级特性

一、单元测试

使用Junit框架

二、反射

反射可以破坏封装性,得到一个类的所有成分,最重要的途径是用来参与Java框架制作。
获取Class对象的三种方式

  • Class c1 = 类名.class
  • 调用Class提供方法: public static Class forName(String package);
  • Object提供的方法: public Class getClass(); Class c3 = 对象.getClass();

反射案例

需求:对于任意对象,将对象的字段名和对应的值保存到文件中去
假设我们有Teacher类和Student类,那么代码如下

language-java
1
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-java
1
2
3
4
5
6
7
public @interface MyAnnotation {

String aaa();
boolean bbb() default true;
String[] ccc();
}

注解二如下

language-java
1
2
3
4
public @interface MyAnnotation2 {

String value();
}

注解使用如下

language-java
1
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-java
1
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-java
1
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-java
1
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-java
1
2
3
4
5
6
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {


}

这是运行代码

language-java
1
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-java
1
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-java
1
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-java
1
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-java
1
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("--------------------");

}
}
作者

Xiamu

发布于

2023-10-14

更新于

2024-08-11

许可协议

评论