注解
什么是注解
内置注解
元注解
自定义注解
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 {
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动态
反射是什么
反射应用
Class类

获得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 c1 = person.getClass(); System.out.println(c1.hashCode());
Class c2 = Class.forName("annotation.Student"); System.out.println(c2.hashCode());
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对象
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;
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;
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);
int[] a = new int[10]; int[] b = new int[100]; System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
|
类加载内存分析
加载,链接,初始化
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类的无参构造初始化"); } }
|
什么时候类初始化
类的主动引用
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 { Son son = new Son();
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.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; }
|
类加载器的作用
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);
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("============");
Field[] fields = c1.getFields(); for (Field field : fields) System.out.println(field);
fields = c1.getDeclaredFields(); for (Field field : fields) System.out.println(field);
Field name = c1.getDeclaredField("name"); System.out.println(name);
System.out.println("=============");
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)
|
反射动态创建对象
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 c1 = Class.forName("reflection.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); } }
|
反射操作注解
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.*;
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(); }
|