注解与反射

注解

什么是注解

image-20220818110715037

内置注解

image-20220818110807620

元注解

image-20220818112230548

自定义注解

image-20220818113842581
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
package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class Test01 {
@MyAnnottation(schools = {"123"})
public void test() {
}

@MyAnnottation2("a")
public void test2() {

}
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnottation {

// 注解的参数:参数类型 + 参数名() 也可以用deflaut设置默认值
String name() default "";
int age() default 0;
int id() default -1;

String[] schools();
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnottation2 {
String value();
}

反射

在游戏运行的时候,把新的代码注入(跑进去)。用Hook(钩子),在游戏运行的时候,改变游戏的数据。

还可以获取注解,获取类的所有东西

静态VS动态

image-20220818123502577

反射是什么

image-20220818123827690

反射应用

image-20220818124004341

Class类

image-20220818131328105

image-20220818131645779

获得Class类

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package annotation;

public class test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println(person.name);

// 通过对象获得Class类
Class c1 = person.getClass();
System.out.println(c1.hashCode());

// 通过forname获得
Class c2 = Class.forName("annotation.Student");
System.out.println(c2.hashCode());

// 通过 类名.Class获得
Class<Student> c3 = Student.class;
System.out.println(c3.hashCode());

// 获得父类类型
Class c4 = c1.getSuperclass();
System.out.println(c4);
}
}

class Person {
public String name;

public Person() {
}

public Person(String name) {
this.name = name;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}

class Student extends Person {
public Student() {
this.name = "学生";
}
}

class Teacher extends Person {
public Teacher() {
this.name = "老师";
}
}

哪些类有Class对象

image-20220818140504813
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
package annotation;

import javax.xml.bind.Element;
import java.lang.annotation.ElementType;

// 所有类型的Class
public class Test04 {
public static void main(String[] args) {
Class c1 = Object.class; // 类
Class c2 = Comparable.class; // 接口
Class c3 = String[].class; // 一维数组
Class c4 = int[][].class; // 二维数组
Class c5 = Override.class; // 注解
Class c6 = ElementType.class; // 枚举
Class c7 = Integer.class; // 包装类
Class c8 = void.class; // 空
Class c9 = Class.class; // Class类

System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);

// 两个长度不一样的数组,底层的Class也是同一个
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
}

类加载内存分析

image-20220726201527382 image-20220818141620483

加载,链接,初始化

image-20220818141838560 image-20220818143158894

1.加载到内存,会产生一个类对应的Class对象

2.链接,链接结束后m=0

3.初始化<clinit> clinit就是class init的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package annotation;

public class test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}

class A {
static {
System.out.println("A类静态代码块初始化");
m = 300;
}

static int m = 100;

public A() {
System.out.println("A类的无参构造初始化");
}
}

什么时候类初始化

image-20220818144003397

类的主动引用

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
package reflection;

public class Test06 {
static {
System.out.println("Main类被加载");
}

public static void main(String[] args) throws ClassNotFoundException {
// 1.主动引用
Son son = new Son();

// 2.反射也会产生主动引用
Class.forName("reflection.Son");
}
}

class Father {
static int b = 2;

static {
System.out.println("父类被加载");
}
}

class Son extends Father {
static {
System.out.println("子类被加载");
m = 300;
}

static int m = 100;
static final int M = 1;
}

类的被动引用

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
package reflection;

public class Test06 {
static {
System.out.println("Main类被加载");
}

public static void main(String[] args) throws ClassNotFoundException {
// System.out.println(Son.b);

// Son[] array = new Son[5];

System.out.println(Son.M);
}
}

class Father {
static int b = 2;

static {
System.out.println("父类被加载");
}
}

class Son extends Father {
static {
System.out.println("子类被加载");
m = 300;
}

static int m = 100;
static final int M = 1;
}

类加载器的作用

image-20220818145639189 image-20220818145733591
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
package reflection;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

public class test07 {
public static void main(String[] args) throws ClassNotFoundException {
// 获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);

// 获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);

// 获取扩展类加载器的父类加载器-->根加载器
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);

// 测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("reflection.test07").getClassLoader();
System.out.println(classLoader);

// 测试JDK内置的类是谁加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
}
}
1
2
3
4
5
6
结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1b6d3586
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null

通过Class对象获得类的信息

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("reflection.User");

// 获得类的名字
System.out.println(c1.getName()); // 包名 + 类名
System.out.println(c1.getSimpleName()); // 类名

System.out.println("============");

// 找到类的public属性
Field[] fields = c1.getFields();
for (Field field : fields)
System.out.println(field);

// 找到类的全部的属性
fields = c1.getDeclaredFields();
for (Field field : fields)
System.out.println(field);

// 获得指定属性的值
// c1.getField("name");
Field name = c1.getDeclaredField("name");
System.out.println(name);

System.out.println("=============");


// 获得本类和父类的全部public方法
Method[] methods = c1.getMethods();
for (Method method : methods)
System.out.println("正常的:" + method);

// 获得本类的所有方法
methods = c1.getDeclaredMethods();
for (Method method : methods)
System.out.println("getDeclaredMethods:" + method);

System.out.println("=================");

// 获得指定方法,后面要接参数类型,因为要识别方法重载
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);

System.out.println("===============");

// 获得构造器(构造方法)
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors)
System.out.println(constructor);

constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors)
System.out.println("getDeclaredConstructors:" + constructor);

// 获得指定的构造器(构造方法)
Constructor declaredConstructors = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println("指定:" + declaredConstructors);
}
}
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
38
39
40
结果:
annotation.User
User
============
private java.lang.String annotation.User.name
private int annotation.User.id
private int annotation.User.age
private java.lang.String annotation.User.name
=============
正常的:public java.lang.String annotation.User.toString()
正常的:public java.lang.String annotation.User.getName()
正常的:public int annotation.User.getId()
正常的:public void annotation.User.setName(java.lang.String)
正常的:public void annotation.User.setId(int)
正常的:public int annotation.User.getAge()
正常的:public void annotation.User.setAge(int)
正常的:public final void java.lang.Object.wait() throws java.lang.InterruptedException
正常的:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
正常的:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
正常的:public boolean java.lang.Object.equals(java.lang.Object)
正常的:public native int java.lang.Object.hashCode()
正常的:public final native java.lang.Class java.lang.Object.getClass()
正常的:public final native void java.lang.Object.notify()
正常的:public final native void java.lang.Object.notifyAll()
getDeclaredMethods:public java.lang.String annotation.User.toString()
getDeclaredMethods:public java.lang.String annotation.User.getName()
getDeclaredMethods:public int annotation.User.getId()
getDeclaredMethods:public void annotation.User.setName(java.lang.String)
getDeclaredMethods:public void annotation.User.setId(int)
getDeclaredMethods:public int annotation.User.getAge()
getDeclaredMethods:public void annotation.User.setAge(int)
=================
public java.lang.String annotation.User.getName()
public void annotation.User.setName(java.lang.String)
===============
public annotation.User()
public annotation.User(java.lang.String,int,int)
getDeclaredConstructors:public annotation.User()
getDeclaredConstructors:public annotation.User(java.lang.String,int,int)
指定:public annotation.User(java.lang.String,int,int)

反射动态创建对象

image-20220818164604907
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

// 动态的创建对象,通过反射
public class test09 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
// 获得Class对象
Class c1 = Class.forName("reflection.User");

// 构造一个对象,本质上是调用User类的无参构造器,如果没有无参构造器,就会报错
User user = (User)c1.newInstance();
System.out.println(user);

// 通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user2 = (User)constructor.newInstance("郭霖", 001, 18);
System.out.println(user2);

user2.setName("guolin");
System.out.println(user2);
}
}

反射操作注解

image-20220821210038519
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package reflection;

import com.sun.deploy.security.ValidationState;

import java.lang.annotation.*;

// 反射操作注解,了解ORM
public class test12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("reflection.Student2");

// 通过反射获取类的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}

// 获得类的注解
Table table = (Table)c1.getAnnotation(Table.class);
String value = table.value();
System.out.println(value);

// 获得变量的注解
java.lang.reflect.Field f = c1.getDeclaredField("name");
Field annotation = f.getAnnotation(Field.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}

@Table("db_student")
// 实体类,假设这是一个数据库
class Student2{

@Field(columnName = "db_id", type = "int", length = 10)
private int id;
@Field(columnName = "db_age", type = "int", length = 10)
private int age;
@Field(columnName = "db_name", type = "varchar", length = 3)
private String name;

public Student2() {
}
}

// 类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table {
String value();
}

// 属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field {
String columnName();
String type();
int length();
}
-------------本文结束感谢您的阅读-------------