1反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2反射机制能做什么
反射机制主要提供了以下功能: 
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。

3反射机制的相关API
通过一个对象获得完整的包名和类名
实例化一个类对象(使用构造函数,默认的和带参数的)
返回一个类实现的接口
取得一个类的父类
获得一个类的全部构造函数
可以通过反射调用一个类的方法
调用一个类的set和get方法
通过反射操作属性
通过反射取得并修改数组的信息
通过反射修改数组大小

就看看下面的各式各样的例子,来一步一步的看看反射都能干些什么,都能干嘛,比空谈理论强多了。

例子虽然海了去了,但是耐心看一半,估计你就赢啦。

【案例1】通过一个对象获得完整的包名和类名

package Reflect;/*** 通过一个对象获得完整的包名和类名*/
class Demo {//other codes...
}class hello {public static void main(String[] args) {Demo demo = new Demo();System.out.println(demo.getClass().getName());}
}

【运行结果】:Reflect.Demo

【案例2】实例化Class类对象

package Reflect;class Demo {//other codes...
}class hello {public static void main(String[] args) {Class<?> demo1 = null;Class<?> demo2 = null;Class<?> demo3 = null;try {//一般尽量采用这种形式demo1 = Class.forName("Reflect.Demo");} catch (Exception e) {e.printStackTrace();}demo2 = new Demo().getClass();demo3 = Demo.class;System.out.println("类名称   " + demo1.getName());System.out.println("类名称   " + demo2.getName());System.out.println("类名称   " + demo3.getName());}
}

【运行结果】:
类名称   Reflect.Demo
类名称   Reflect.Demo
类名称   Reflect.Demo

【案例3】通过Class实例化其他类的对象
通过无参构造实例化对象

package Reflect;class Person {private String name;private int age;//getters and setters@Overridepublic String toString() {return "[" + this.name + "  " + this.age + "]";}
}class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}Person per = null;try {per = (Person) demo.newInstance();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}per.setName("Rollen");per.setAge(20);System.out.println(per);}
}

【运行结果】:
[Rollen  20]
但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:
比如我定义了一个构造函数:

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

然后继续运行上面的程序,会出现:

java.lang.InstantiationException: Reflect.Person

at java.lang.Class.newInstance0(Class.java:340)

at java.lang.Class.newInstance(Class.java:308)

at Reflect.hello.main(hello.java:39)

Exception in thread "main" java.lang.NullPointerException

at Reflect.hello.main(hello.java:47)

所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数

比如我的这个bug也是因为这个默认构造函数的问题,实例化对象就出错了。具体如下:

因为少了默认构造方法而引发的bug

【案例4】通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)

package Reflect;import java.lang.reflect.Constructor;class Person {private String name;private int age;public Person() {}public Person(String name) {this.name = name;}public Person(int age) {this.age = age;}public Person(String name, int age) {this.age = age;this.name = name;}//getters and setters@Overridepublic String toString() {return "[" + this.name + "  " + this.age + "]";}
}class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}Person per1 = null;Person per2 = null;Person per3 = null;Person per4 = null;//取得全部的构造函数Constructor<?> cons[] = demo.getConstructors();try {per1 = (Person) cons[0].newInstance();per2 = (Person) cons[1].newInstance("Rollen");per3 = (Person) cons[2].newInstance(20);per4 = (Person) cons[3].newInstance("Rollen", 20);} catch (Exception e) {e.printStackTrace();}System.out.println(per1);System.out.println(per2);System.out.println(per3);System.out.println(per4);}
}

【运行结果】:
[null  0]
[Rollen  0]
[null  20]
[Rollen  20]

【案例5】返回一个类实现的接口:

package Reflect;interface China {//public static final String name = "Rollen";//接口中声明前面的类型等修饰符都是多余的String name = "Rollen";int age = 20;void sayChina();void sayHello(String name, int age);
}class Person implements China {private String sex;public Person() {}public Person(String sex) {this.sex = sex;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic void sayChina() {System.out.println("hello ,china");}@Overridepublic void sayHello(String name, int age) {System.out.println(name + "  " + age);}
}class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}//保存所有的接口Class<?> intes[] = demo.getInterfaces();for (int i = 0; i < intes.length; i++) {System.out.println("实现的接口   " + intes[i].getName());}}
}

【运行结果】:
实现的接口   Reflect.China

(注意,以下几个例子,都会用到这个例子的Person类,所以为节省篇幅,此处不再粘贴Person的代码部分,只粘贴主类hello的代码)

【案例6】:取得其他类中的父类

class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}//取得父类Class<?> temp = demo.getSuperclass();System.out.println("继承的父类为:   " + temp.getName());}
}

【运行结果】
继承的父类为:   java.lang.Object

【案例7】:获得其他类中的全部构造函数
这个例子需要在程序开头添加import java.lang.reflect.*;
然后将主类编写为:

import java.lang.reflect.Constructor;class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}Constructor<?> cons[] = demo.getConstructors();for (int i = 0; i < cons.length; i++) {System.out.println("构造方法:  " + cons[i]);}}
}

【运行结果】:
构造方法:  public Reflect.Person()
构造方法:  public Reflect.Person(java.lang.String)

【案例8】接下来让我们取得其他类的全部属性吧,最后我讲这些整理在一起,也就是通过class取得一个类的全部框架

import java.lang.reflect.Modifier;class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}System.out.println("===============本类属性========================");// 取得本类的全部属性Field[] field = demo.getDeclaredFields();for (int i = 0; i < field.length; i++) {// 权限修饰符int mo = field[i].getModifiers();String priv = Modifier.toString(mo);// 属性类型Class<?> type = field[i].getType();System.out.println(priv + " " + type.getName() + " "+ field[i].getName() + ";");}System.out.println("===============实现的接口或者父类的属性========================");// 取得实现的接口或者父类的属性Field[] filed1 = demo.getFields();for (int j = 0; j < filed1.length; j++) {// 权限修饰符int mo = filed1[j].getModifiers();String priv = Modifier.toString(mo);// 属性类型Class<?> type = filed1[j].getType();System.out.println(priv + " " + type.getName() + " "+ filed1[j].getName() + ";");}}
}

【运行结果】:
===============本类属性========================
private java.lang.String sex;
===============实现的接口或者父类的属性========================
public static final java.lang.String name;
public static final int age;

【案例9】其实还可以通过反射调用其他类中的方法:

import java.lang.reflect.Method;class hello {public static void main(String[] args) {Class<?> demo = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}try {//调用Person类中的sayChina方法Method method = demo.getMethod("sayChina");method.invoke(demo.newInstance());//调用Person的sayHello方法method = demo.getMethod("sayHello", String.class, int.class);method.invoke(demo.newInstance(), "Rollen", 20);} catch (Exception e) {e.printStackTrace();}}
}

【运行结果】:
hello ,china
Rollen  20

【案例10】调用其他类的set和get方法

import java.lang.reflect.Method;class hello {public static void main(String[] args) {Class<?> demo = null;Object obj = null;try {demo = Class.forName("Reflect.Person");} catch (Exception e) {e.printStackTrace();}try {obj = demo.newInstance();} catch (Exception e) {e.printStackTrace();}setter(obj, "Sex", "男", String.class);getter(obj, "Sex");}/*** @param obj 操作的对象* @param att 操作的属性*/public static void getter(Object obj, String att) {try {Method method = obj.getClass().getMethod("get" + att);System.out.println(method.invoke(obj));} catch (Exception e) {e.printStackTrace();}}/*** @param obj   操作的对象* @param att   操作的属性* @param value 设置的值* @param type  参数的属性*/public static void setter(Object obj, String att, Object value, Class<?> type) {try {Method method = obj.getClass().getMethod("set" + att, type);method.invoke(obj, value);} catch (Exception e) {e.printStackTrace();}}
}// end class

【运行结果】:

【案例11】通过反射操作属性

import java.lang.reflect.Field;class hello {public static void main(String[] args) throws Exception {Class<?> demo = null;Object obj = null;demo = Class.forName("Reflect.Person");obj = demo.newInstance();Field field = demo.getDeclaredField("sex");field.setAccessible(true);field.set(obj, "男");System.out.println(field.get(obj));}
}// end class

【案例12】通过反射取得并修改数组的信息:

import java.lang.reflect.*;class hello {public static void main(String[] args) {int[] temp = {1, 2, 3, 4, 5};Class<?> demo = temp.getClass().getComponentType();System.out.println("数组类型: " + demo.getName());System.out.println("数组长度  " + Array.getLength(temp));System.out.println("数组的第一个元素: " + Array.get(temp, 0));Array.set(temp, 0, 100);System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));}
}

【运行结果】:
数组类型: int
数组长度  5
数组的第一个元素: 1
修改之后数组第一个元素为: 100

【案例13】通过反射修改数组大小

import java.lang.reflect.Array;class hello {public static void main(String[] args) {int[] temp = {1, 2, 3, 4, 5, 6, 7, 8, 9};int[] newTemp = (int[]) arrayInc(temp, 15);print(newTemp);System.out.println("=====================");String[] atr = {"a", "b", "c"};String[] str1 = (String[]) arrayInc(atr, 8);print(str1);}/*** 修改数组大小*/public static Object arrayInc(Object obj, int len) {Class<?> arr = obj.getClass().getComponentType();Object newArr = Array.newInstance(arr, len);int co = Array.getLength(obj);System.arraycopy(obj, 0, newArr, 0, co);return newArr;}/*** 打印*/public static void print(Object obj) {Class<?> c = obj.getClass();if (!c.isArray()) {return;}System.out.println("数组长度为: " + Array.getLength(obj));for (int i = 0; i < Array.getLength(obj); i++) {System.out.print(Array.get(obj, i) + " ");}}
}

【运行结果】:
数组长度为: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
数组长度为: 8
a b c null null null null null

java反射详解---具体代码操作看看反射都能干些什么相关推荐

  1. java unsafe 详解_Java CAS操作与Unsafe类详解

    一.复习 计算机内存模型,synchronized和volatile关键字简介 二.两者对比 sychronized和volatile都解决了内存可见性问题 不同点: (1)前者是独占锁,并且存在者上 ...

  2. Java :反射详解

    Java 反射详解 目录 Java 反射详解 1.什么是反射? 2.反射能做什么? 3.反射的具体实现 4.根据反射获取父类属性 4.反射总结 1.什么是反射? Java反射就是在运行状态中,对于任意 ...

  3. java 7 反射_【7】java 反射详解

    [7]java 反射详解 获取Class对象的方式: 1. Class.forName("全类名"); 将字节码加载进内存,返回Class对象,多用于配置文件,将类名定义在配置文件 ...

  4. java集合框架的结构_集合框架(Collections Framework)详解及代码示例

    简介 集合和数组的区别: 数组存储基础数据类型,且每一个数组都只能存储一种数据类型的数据,空间不可变. 集合存储对象,一个集合中可以存储多种类型的对象.空间可变. 严格地说,集合是存储对象的引用,每个 ...

  5. flask与js交互的示例代码_Frida Java Hook 详解(安卓9):代码及示例(上)

    Frida Java Hook 详解(安卓9):代码及示例(上) 前言 1.1 FRIDA SCRIPT的"hello world" 1.1.1 "hello world ...

  6. Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例

    Java 泛型(generics)详解及代码示例.Java 类型通配符详解及代码示例 - 概念 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制 ...

  7. Java数据结构与算法-SingleLinkedList单向链表插入,删除,查找,修改详解及代码

    SingleLinkedList单向链表插入,删除,查找,修改详解及代码 单向链表学习目标 1. 链表的介绍 2. 单向链表的存储特点以及原理 3. 基本操作:插入,删除等 4. 单向链表应用场景举例 ...

  8. 模板方法模式详解附有代码案例分析(包含模板方法模式重构JDBC操作业务代码示例)

    模板方法模式 一.模板方法模式的概念和角色 (一).模板方法模式的概念 (二).模板方法模式的角色 二.模板方法模式的应用场景 三. 模板方法模式的代码示例 四.模板方法模式重构JDBC操作业务 五. ...

  9. java实现标准化考试系统详解(四)-----初始化操作实现

    (一)初始化操作实现 如上图所示当管理员需要更改适用工程.试题数量.考试时间时直接在文本中更改就好我们只需要每次在用户打开程序时初始化这些参数就可以 1.初始化试题模型,这里需要实现随机抽题,方法是用 ...

最新文章

  1. Ubuntu14.04 64位机上安装OpenCV2.4.13(CUDA8.0)版操作步骤
  2. Android 轮询最佳实践 Service + AlarmManager+Thread
  3. FPGA的设计艺术(15)逻辑设计及仿真利器之各式各样的循环
  4. 解析 http 请求 header 错误_详解http报文(2)-web容器是如何解析http报文的
  5. python kotlin_在Python,Java和Kotlin中标记参数和重载
  6. 怎么实现注解_通透!一口气搞懂注解到底怎么用
  7. 思达报表工具Style Report基础教程—创建一个多数据块的联合(Union)、镜像(Mirror)...
  8. $ 在 JQuery 里的意思
  9. python简明教程_05
  10. AR.js摄像头前置的问题(已解决)(H5调用摄像头)
  11. serializer嵌套序列化
  12. 信息系统监理师考试知识点整理
  13. 科学计算机安卓图像,图形科学计算器Pro
  14. LQBv13-Python:猜年龄
  15. 使用PowerPhotos for Mac查找重复项似乎缺少一些重复的照片的解决办法
  16. 前端设置div的显示与隐藏
  17. 10个Excel实用操作技巧分享,使用率超高,让你一学就会
  18. 前端下载 “不支持打开该类型文件或文件已损坏“问题
  19. 18北大考研经验贴汇总
  20. axios进行二次封装

热门文章

  1. 王常在主任提醒家长要警惕孩子语言发育迟缓!怎样判断语言发育是否迟缓?
  2. 基于C++的http服务端开发
  3. webstorm 常用快捷键大全归纳总结
  4. 腾讯8分钟产品课—用户
  5. Crosswalk Project for Linux
  6. 【intel IPP库历史版本下载】
  7. 3自由度并联绘图机器人实现写字功能(一)
  8. 智能资产构建去中心化的资产管理系统
  9. 电脑桌面上记录每天需要完成工作的便签软件下载哪一个
  10. DB2副本DB2COPY1DB2COPY2