反射
概念:类加载之后,在堆内存的方法区中就生产了一个Class类型的对象,一个类只有一个Class对象
,这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构,这个对象就像是一面镜子,透过这个镜子看到类的结构,称之为反射
正常方式:引入需要的”包类”名称 ==> 通过new实例化 ==>获取实例化对象
反射方式:实例化对象 ==> getClass()方法 ==> 取得完整的”包类”名称
- 优点:可以实现动态创建对象和编译,体现出很大的灵活性
- 缺点:对性能有影响。使用反射基本上是一种解释操作,我们告诉JVM要做什么,这类操作总是慢于直接执行相同的操作
一个类只有一个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
| public class Test02 { public static void main(String[] args) throws ClassNotFoundException { Person student = new Studnet();
Class c1 = student.getClass(); System.out.println(c1.hashCode());
Class c2 = Class.forName("Student"); System.out.println(c2.hashCode());
Class c3 = Student.class; System.out.println(c3.hashCode());
Class c4 = Integer.TYPE; System.out.println(c4); } }
class Studnet extends Person{
}
class Person {
}
|
所有类型的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
| public class Test02 { 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); } }
|
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
| public class Test02 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("Student");
System.out.println(c1.getName()); System.out.println(c1.getSimpleName());
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(method); }
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(constructor); }
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class); System.out.println(declaredConstructor); } }
|
类的加载过程
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 Test02 { static { System.out.println("Main类被加载"); }
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("Son");
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("子类被加载"); }
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
| public class Test02 {
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("Test02").getClassLoader(); System.out.println(classLoader);
classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader);
} }
|
双亲委派机制
反射操作对象
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
| public class Test02 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Class c1 = Class.forName("Student");
Student student = (Student) c1.newInstance();
Constructor constructor = c1.getDeclaredConstructor(String.class,int.class); Student student1 = (Student)constructor.newInstance("小明",18);
Student student2 = (Student) c1.newInstance(); Method setName = c1.getDeclaredMethod("setName",String.class); setName.invoke(student2,"张三"); System.out.println(student2);
Student student3 = new Student(); Field name = c1.getDeclaredField("name"); name.setAccessible(true); name.set(student3,"李四"); System.out.println(student3); } }
|
反射操作泛型
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
| public class Test02 { public static void main(String[] args) throws NoSuchMethodException { Method method = Test02.class.getMethod("test1", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println(genericParameterType); if (genericParameterType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } }
method = Test02.class.getMethod("test2",null); Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } }
}
public void test1(Map<String,String> map, List<String> list) { System.out.println("test01"); }
public List<String> test2() { return null; } }
|
反射操作注解
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 69 70 71 72 73 74 75 76 77 78
| public class Test02 { public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("Student"); Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); }
MyAnnotation annotation = (MyAnnotation) c1.getAnnotation(MyAnnotation.class); System.out.println(annotation.value());
Field f = c1.getDeclaredField("name"); MyAnnotation2 annotation1 = f.getAnnotation(MyAnnotation2.class); System.out.println(annotation1.columnName()); System.out.println(annotation1.type()); System.out.println(annotation1.length()); } }
@MyAnnotation("student") class Student { @MyAnnotation2(columnName = "name",type = "String",length = 10) private String name; @MyAnnotation2(columnName = "age",type = "int",length = 4) private int age;
public Student() { }
public Student(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String value(); }
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2 { String columnName(); String type(); int length(); }
|