JAVA-注解和反射二{反射机制}JAVA从基础开始 --4
反射机制
+JVM 讲解 运行时候创建对象(classLoader)
java反射机制概述
Java Reflection—反射机制
Java反射机制研究及应用
优点
缺点
主要api
Class类
Class类的常用方法
方法名 | 功能说明 |
---|---|
static Classforname(String name) | 返回指定类名name的 Class对象 |
Object newlnstance() | 调用缺省构造函数,返回 Class对象的一个实例 |
getName() | 返回此Cass对象所表示的实体(类,接口,数组类或void)的名称 |
Class getSuperClass() | 返回当前Cass对象的父类的Cass对象 |
Class[] getinterfaces() | 获取当前 Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Constructor[] getConstructors() | 返回一个包含某些 Constructor对象的数组 |
Method getMothed( String name, Class.T) | 返回一个 Method对象,此对象的形参类型为paramType |
Field[] getDeclaredFelds() | 返回Feld对象的一个数组 |
哪些类型可以有Cas对象?
Java内存分析存放new的对象和数组堆可以被所有的线程共享,不会存放别的对象引用存放基本变量类型(会包含这个基本类型的具体数值)Java内存栈引用对象的变量(会存放这个引用在堆里面的具体地址)可以被所有的线程共享方法区包含了所有的 class和 static变量
◆初始化
# 类的初始化
什么时候会发生类初始化?类的主动引用(一定会发生类的初始化)
package main.Reflection;
//类的主动引用--类会初始化
public class Test06 {
static {
System.out.println("main方法被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
// Son son = new Son();
//反射也会产生引用
Class.forName("main.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;
}
类的被动引用(不会发生类的初始化)
类加载器的作用
package main.Reflection;
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);
// //获取扩展类加载器的父类加载器 --》根加载器(c,c++)
// ClassLoader parent1 = parent.getParent();
// System.out.println(parent1);
//
// //测试当前类是哪个加载器加载的
// ClassLoader classLoader = Class.forName("main.Reflection.Test07").getClassLoader();
// System.out.println(classLoader);
// //测试jdk内置类是哪个加载器加载的
// ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
// System.out.println(classLoader1);
//
//
//如何获得系统类加载器加载的路径
String property = System.getProperty("java.class.path");
System.out.println(property);
//双委派机制
//java.lang.String---->用户类加载器--->根加载器
//如果手写了个java.lang.String,不会运行,而是会找到根加载器上的来用
/**
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;
* C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;
* E:\obj\ideaObj\annotation\out\production\annotation;
* D:\idear\IntelliJ IDEA 2021.2\lib\idea_rt.jar
*/
}
}
创建运行时类的对象
package main.Reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获得类的信息
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("main.Reflection.User");
// User user = new User();
// c1 = user.getClass();
//获得类的名字
System.out.println(c1.getName());//包名加类名
System.out.println(c1.getSimpleName());//类名
//获得类的属性
System.out.println("===========类的属性=========");
Field[] fields = c1.getFields();//只能找到public属性
// for (Field field : fields) {
// System.out.println(field);// 打印不出来
// }
fields = c1.getDeclaredFields();//找到所有属性
for (Field field : fields) {
System.out.println(field);
}
Field name = c1.getDeclaredField("name");//从全部属性中找 private name
// Field name1 = c1.getField("name");//只能找public属性 没有public的name属性
System.out.println(name);
//获得方法
System.out.println("===========getMethods=========");
Method[] methods = c1.getMethods();// 获得本类及其父类的全部public方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("===========getDeclaredMethods=========");
Method[] methods1 = c1.getDeclaredMethods();//获得本类的所有方法
for (Method method : methods1) {
System.out.println(method);
}
}
}
动态创建对象执行方法
package main.Reflection;
import java.lang.reflect.Field;
//动态创建对象,通过反射
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//获得Class对象
Class c1= Class.forName("main.Reflection.User");
//构造一个对象
User user = (User)c1.newInstance();//调用无参构造器
System.out.println(user);
System.out.println("=======================");
User user1 = (User)c1.newInstance();//调用无参构造器
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,需要关闭程序的安全检测 setAccessible(true)
name.setAccessible(true);//权限检查 使private失效,默认false不启用,true是启用
name.set(user1,"小学生");
System.out.println(user1.getName());
}
}
调用指定方法
setAccessible
性能检测
package main.Reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//分析性能问题
public class Test10 {
//普通方式调用
public static void test01() {
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
}
//反射方式调用
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
}
//反射方式调用
public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭检测反射方式执行getName十亿次需要的时间:" + (endTime - startTime) + "ms");
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
test01();
test02();
test03();
}
}
获取泛型信息
反射操作泛型
package main.Reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
//通过反射获取泛型
public class Test11 {
public void test01(Map<String, User> map, List<User> list) {
System.out.println("01");
}
public Map<String, User> test02() {
System.out.println("02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method me = Test11.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = me.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);
}
}
}
me = Test11.class.getMethod("test02", null);
Type genericReturnType = me.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("##" + actualTypeArgument);
}
}
}
}
获取注解信息
package main.Reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
//联系反射操作注解
public class Test12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("main.Reflection.Student2");
//通过反射获取注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解value的值
TableCloud tableCloud = (TableCloud) c1.getAnnotation(TableCloud.class);
String value = tableCloud.value();
System.out.println(value);
//获得类指定的注解
Field f = c1.getDeclaredField("id");
FieldCloud annotation = f.getAnnotation(FieldCloud.class);
System.out.println(annotation.conlumnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
@TableCloud("db_student")
class Student2 {
@FieldCloud(conlumnName = "db_id", type = "int", length = 10)
private int id;
@FieldCloud(conlumnName = "db_age", type = "int", length = 10)
private int age;
@FieldCloud(conlumnName = "db_name", type = "String", length = 3)
private String name;
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//类名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableCloud {
String value();
}
//属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldCloud {
String conlumnName();
String type();
int length();
}