获取类的运行时状态

//获取类的信息
public class Test05 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName("com.mayb.demo02.Son");Son01 son01 = new Son01();//通过反射c1 = son01.getClass();System.out.println(c1.getName());//获取类的名称  包名 + 类名System.out.println(c1.getSimpleName());//获取类的简单名称  类名}
}class Son01{private int m = 10;
}

通过反射获取运行时类的完整结构
Field(属性)、Method(方法)、Constructor(构造器)、 Superclass(父类)、 Interface(接口)、 Annotation(注解)

实现的全部接口 ,所继承的父类,全部的构造器,全部的方法,全部的Field,注解等

获取在运行时类的完整结构

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;//获取类的信息
public class Test05 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 = Class.forName("com.mayb.demo02.Son");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 m = c1.getDeclaredField("m");//获取指定属性System.out.println(m);System.out.println("<-------------------------->");//获取类的方法Method[] methods = c1.getMethods(); // 包括本类和父类的全部public方法for (Method method : methods) {System.out.println("public : "+method);}methods = c1.getDeclaredMethods();//仅获取本类的所有方法for (Method method : methods) {System.out.println("全部的 : "+ method);}//获取指定方法 小心重载Method method = c1.getMethod("aVoid", String.class); //需要publicSystem.out.println(method);method = c1.getDeclaredMethod("cVoid", String.class);//这个是全部的System.out.println(method);method = c1.getMethod("bVoid", String.class, int.class, int.class);System.out.println(method);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("All : "+constructor);}//获取指定的构造器Constructor constructor = c1.getConstructor(int.class, int.class);System.out.println(constructor);constructor = c1.getDeclaredConstructor();System.out.println("All"+constructor);}
}

Class.forName 的Son类

public class Son {private int m = 100;public  int M = 1;public void aVoid(String a ){}private void cVoid(String a ){}public void  bVoid(String a ,int b,int c){}public Son() {}public Son(int m, int m1) {this.m = m;M = m1;}
}

使用反射操作对象

创建类的对象:调用Class对象的newInstance()方法

  1. 类必须有一个无参数的构造器。
  2. 类的构造器的访问权限需要足够

思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,
并将参数传递进去之后,才可以实例化操作。

步骤如下:

  1. 通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构
    造器
  2. 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
  3. 通过Constructor实例化对象
//动态的创建对象,通过反射
public class Test05 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {// 获得Class对象Class c1 = Class.forName("com.mayb.demo02.Son");// 构造一个对象Son son1 = (Son) c1.newInstance();//本质上调用无参构造 没无参构造就会错误System.out.println(son1);//通过构造器构造对象Constructor constructor =  c1.getConstructor(int.class,int.class);Son son2 = (Son) constructor.newInstance(1,1);System.out.println(son2);//  通过反射调用方法Son son3 = (Son) c1.newInstance();Method method =  c1.getDeclaredMethod("setName", String.class);//给那个对象调用方法传入的参数 invoke 激活方法//第一参数为对象  第二为参数值method.invoke(son3,"Mayb");System.out.println(son3.getName());// 通过反射操作属性Son son4 = (Son) c1.newInstance();Field name = c1.getDeclaredField("name");//不能为私有的属性// 是否开启关闭检查 开启了就可以给私有属性设值(程序的安全检测 setAccessible)name.setAccessible(true);//降低程序效率name.set(son4,"Mayb2");System.out.println(son4.getName());}
}

setAccessible

  1. Method和Field、Constructor对象都有setAccessible()方法。
  2. setAccessible作用是启动和禁用访问安全检查的开关。
  3. 参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。
    • 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。
    • 使得原本无法访问的私有成员也可以访问
  4. 参数值为false则指示反射的对象应该实施Java语言访问检查
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;//分析性能问题
public class Test06 {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {test01();test02();test03();}// 普通方式调用public static void test01(){Son son = new Son("Mayb");long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {son.getName();}long endTime = System.currentTimeMillis();System.out.println("普通方法执行时间:" + (endTime - startTime));}// 反射方式调用public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Son son = new Son("Mayb");Class c1 = son.getClass();Method getName = c1.getDeclaredMethod("getName",null);long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {getName.invoke(son,null);}long endTime = System.currentTimeMillis();System.out.println("反射方式调用:" + (endTime - startTime));}// 反射方式调用  关闭安全检查public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Son son = new Son("Mayb");Class c1 = son.getClass();Method getName = c1.getDeclaredMethod("getName",null);getName.setAccessible(true);long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {getName.invoke(son,null);}long endTime = System.currentTimeMillis();System.out.println("关闭安全检查:" + (endTime - startTime));}
}

结果

普通方法执行时间:3
反射方式调用:1999
关闭安全检查:1320

如果在使用时调用很多次反射方法可以关闭安全检测

通过反射获取泛型

泛型是一种约束机制

  • Java采用泛型擦除的机制来弓|入泛型, Java中的泛型仅仅是给编译器javac使用的,确保数据
    的安全性和免去强制类型转换问题,但是,一旦编译完成,所有和泛型有关的类型全部擦除
  • 为了通过反射操作这些类型, Java新增了ParameterizedType , GenericArrayType,
    TypeVariable和WildcardType几种类型来代表不能被归一到Class类中的类型但是又和原
    始类型齐名的类型.
  • ParameterizedType :表示- -种参数化类型,比如Collection
  • GenericArrayType :表示一种元素类型是参 数化类型或者类型变量的数组类型
  • TypeVariable :是各种类型变量的公共父接口
  • WildcardType :代表一种通配符类型表达式
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 Test07 {public void test01(Map<String,Son> map, List<Son> list){System.out.println("test01");}public Map<String,Son> test02(){System.out.println("test02");return null;}public static void main(String[] args) throws NoSuchMethodException {Method test01 = Test07.class.getDeclaredMethod("test01", Map.class, List.class);Type[] genericParameterTypes = test01.getGenericParameterTypes();for (Type genericParameterType : genericParameterTypes) {System.out.println("genericParameterType : "+genericParameterType);//如果泛型的参数类型 genericParameterType 属于 参数化类型if (genericParameterType instanceof ParameterizedType){//获取真实类型Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}}test01 = Test07.class.getDeclaredMethod("test02",null);Type genericReturnType = test01.getGenericReturnType();//返回类型if (genericReturnType instanceof ParameterizedType){//获取真实类型Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println("actualTypeArgument: " + actualTypeArgument);}}}
}

反操作注解

getAnnotations
getAnnotation

通过注解和反射完成ORM 对象关系映射

import java.lang.annotation.*;
import java.lang.reflect.Field;public class Test08 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("com.mayb.demo02.Student");//通过反射获得注解Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}//获得注解value 的值TableStudent tableStudent = (TableStudent)c1.getAnnotation(TableStudent.class);String value = tableStudent.value();System.out.println(value);//获取类指定的注解Field f = c1.getDeclaredField("id");FieldInterface annotation = f.getAnnotation(FieldInterface.class);System.out.println(annotation.columnName());System.out.println(annotation.type());System.out.println(annotation.length());}}@TableStudent("db_student")
class Student{@FieldInterface(columnName = "db_id",type = "int",length = 10)private int id;@FieldInterface(columnName = "db_age",type = "int",length = 10)private int age;@FieldInterface(columnName = "db_name",type = "varchar",length = 10)private String name;@Overridepublic String toString() {return "Student{" +"id=" + id +", age=" + age +", 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;}public Student() {}public Student(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}
}//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableStudent{String value();
}//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldInterface{String columnName();String type();int length();
}

注解与反射 - 反射 - 操作反射相关推荐

  1. java 获取所有带指定注解的类名_SXT DAY023 反射和注解

    1. 反射机制介绍_Class对象获取 反射机制是 Java 的动态性之一 动态语言:在程序运行时,可以改变程序的结构或变量的 类型. 反射机制的常见作用 动态的加载类.动态的获取类的信息(属性,方法 ...

  2. 【JavaLearn】(19)反射、Class类、使用反射创建对象-操作属性-执行方法、泛型与反射、反射案例

    目录 1. 反射 1.1 反射引入 1.2 反射的入口-Class类 2. 认识 Class 类 3. 使用反射创建对象 4. 使用反射操作属性 5. 使用反射执行方法 6. 使用反射操作泛型 6.2 ...

  3. 【JavaLearn】#(19)反射、Class类、使用反射创建对象-操作属性-执行方法、泛型与反射、反射案例

    1. 反射 1.1 反射引入 编译时,知道类或对象的具体信息,此时直接对类和对象进行操作即可 编译时不知道类或对象的具体信息,只有运行时知道,需要使用反射来实现 ==> 比如驱动的类的名称放在 ...

  4. 【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  5. java动态变量名反射_Java动态性—反射 - Eclipse666的个人空间 - OSCHINA - 中文开源技术交流社区...

    1.什么是动态语言? 程序运行时,可以改变程序的结构或者变量类型:如Python,javaScript function(){ var s="var a=3;var b=4;" e ...

  6. 什么是反射?为什么使用反射?

    反射 一.什么是反射 二.反射的特点 1.优点:主要是其动态性 2.缺点:主要是性能损失 三.实现Java反射机制的类都位于java.lang.reflect包中: 四.使用场景 5.替代方案 六.案 ...

  7. 反射 及 Reflections反射框架

    一.类加载过程 要知道反射机制,还需要理解类的加载过程.总的来说,类加载的五个过程:加载.验证.准备.解析.初始化. 除了加载(装载)阶段,用户可以通过自定义的类加载器参与,其他阶段都完全由虚拟机主导 ...

  8. java 反射代价_Java反射机制

    # 反射 ## 什么是反射 反射是Java提供的动态执行机制, 可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法.. 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行 ...

  9. java 反射机制_Java反射机制原理探究

    反射是Java中的一个重要的特性,使用反射可以在运行时动态生成对象.获取对象属性以及调用对象方法.与编译期的静态行为相对,所有的静态型操作都在编译期完成,而反射的所有行为基本都是在运行时进行的,这是一 ...

  10. 一篇文章弄懂Java反射基础和反射的应用场景

    文章目录 一.Java反射定义 二.Java反射机制实现 1.Class对象获取 2.获取class对象的摘要信息 3.获取class对象的属性.方法.构造函数等 三.反射的应用场景 1.动态代理 2 ...

最新文章

  1. 区块链技术指2.1 区块链技术
  2. linux传输文件无密码,Linux下scp无密码上传 下载 文件 目录
  3. 每日程序C语言30-static作用
  4. Activity Monitor 闪退 无法进入睡眠
  5. 消息队列技术终结者(一)—通俗深刻地认识JMS(即Java Message Service)
  6. 拓端tecdat|【视频】Rapidminer关联规则和文本挖掘模型对评论数据进行分析
  7. python 金融可视化_Python数据分析:金融数据可视化
  8. 【软件工程】-项目开发计划
  9. New Year Garland
  10. 主流量化交易策略:统计套利交易策略
  11. 3w 字长文爆肝 Java 基础面试题!太顶了!!!
  12. 深度学习 | 训练及优化方法
  13. 二代测序的原理和简介
  14. Automation Anywhere视频教程
  15. 年薪6万美元/应届医学博士赴加州大学圣迭戈分校博士后就职
  16. Linq实现In条件和Distinct效果
  17. 如何带好一个20人团队?
  18. js面向对象prototype
  19. 施乐700彩机服务器维修,佳铭办公设备:施乐彩机维修代码
  20. php环境下安装并运行laravel教程

热门文章

  1. 福利篇1——嵌入式软件行业与公司汇总
  2. 离散数学课本上的最短路径算法
  3. 来自“飞人”乔丹的启示!奥尼尔开启的另一个“赛场”
  4. 【SQL注入漏洞-01】SQL注入漏洞原理及分类
  5. 让lynda网站显示中文字幕
  6. 【云计算OpenStack-OpenStack Queens版本】基于OpenStack的云计算环境搭建
  7. 【分享】WebForm中DataGrid的20篇经典文章
  8. 使用Scrapy框架爬取88读书网小说,并保存本地文件
  9. 尼康D90对焦模式图解
  10. 学计算机去什么大学好,去美国学计算机专业什么大学好