Java反射机制
来源:互联网 发布:php 开源社区系统 编辑:程序博客网 时间:2024/06/12 00:55
Java反射是在运行状态中,对于任意一个类,都知道这个类的所有属性和方法;对于任意一个对象,都能调用他的任意方法和属性。这种动态获取信息及动态调用对象方法的功能称为Java语言的反射机制。换句话说,Java程序可以加载一个运行时才知道名称的class,获悉其完整构造,并生成其对象实体,或对其fields设值、或唤醒其methods。(摘自360百科)
在讲反射之前,先了解一下如下几个类:
类类(Class类):Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。(摘自JDK API)
方法类(Method类):Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。(摘自JDK API)
属性类(Field类):Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。(摘自JDK API)
构造器类(Constructor类):Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。 Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,但是如果发生收缩转换,则抛出 IllegalArgumentException。(摘自JDK API)
*注意:当一个类被加载且创建对象时,和该类相关的一个类型为Class的对象就会自动创建,任何对象调用getClass()方法都可以获取和该对象相关的一个Class对象。
Class对象经常调用的方法:
String getName() //返回类的名字 Constructor[] getDeclaredConstructors() //返回类的全部构造方法 Field[] getDeclaredFields() //返回类的全部成员变量 Method[] getDeclaredMethods() //返回类的全部方法
如果说到这里都不太好理解,看看下面它们在代码中的使用方式就好了。
一、反射的作用:
1.通过反射机制发现对象的类型,发现类型的方法、属性、构造函数(在可视化编程的时候获取控件类型用的比较多)
2.可以创建对象并访问任意对象方法和属性
作用1代码示例:
package ex; public class Test { public static void main(String args[]) { Class cls = "abc".getClass(); System.out.println(cls); } } //输出结果: //class java.lang.String
作用2代码示例:
package ex; import java.util.Scanner; public class Test { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Scanner sc = new Scanner(System.in); System.out.println("请选择创建的图形:1.圆形 2.三角形"); int choice = sc.nextInt(); Shape figure = new Shape(); if(choice == 1) { figure = (Shape)Class.forName("ex.Circle").newInstance(); //注:newInstance(): 弱类型。低效率。只能调用无参构造 } else { figure = (Shape)Class.forName("ex.Triangle").newInstance(); } figure.show(); sc.close(); } } class Shape{ void show() { } } class Circle extends Shape{ void show() { System.out.println("这是一个圆"); } }class Triangle extends Shape{ void show() { System.out.println("这是一个三角形"); }}//输出结果:/*请选择创建的图形:1.圆形 2.三角形 *1 *这是一个圆 */
二、Reflection的简单操作示例
示例1:获得想操作类的java.lang.Class对象
eg:
Class cls = Class.forName("java.lang.String");//正常玩法Class cls = char.class; //正常玩法2Class cls = Integer.TYPE; //基本类型封装类的玩法Class cls = "abc".getClass(); //正常玩法3
示例2:获取想操作类的所有方法列表
eg:
package ex; //import java.util.Scanner; import java.lang.reflect.*; public class Test { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Class cls = Class.forName("java.lang.String"); Method[] med = cls.getDeclaredMethods(); for(int i = 0;i<5;i++) { //先打印五个函数,太多了 System.out.println(med[i].toString()); } } }//输出结果:/*public boolean java.lang.String.equals(java.lang.Object) *public java.lang.String java.lang.String.toString() *public int java.lang.String.hashCode() *public int java.lang.String.compareTo(java.lang.String) *public int java.lang.String.compareTo(java.lang.Object) */
示例3:获取想操作类的构造器信息
package ex; //import java.util.Scanner; import java.lang.reflect.*; public class Test { public static void main(String args[]) throws ClassNotFoundException{ Class cls = Class.forName("java.lang.String"); Constructor[] cst = cls.getDeclaredConstructors(); for(int i = 0;i<cst.length;i++) { System.out.println(cst[i]); } } }//输出结果:/*public java.lang.String(java.lang.String) *public java.lang.String(char[],int,int) *public java.lang.String(byte[],int) *public java.lang.String(byte[],int,int,int)*/
示例4:获得想操作类的字段
package ex; //import java.util.Scanner; import java.lang.reflect.*; public class Test { public static void main(String args[]) throws ClassNotFoundException{ Class cls = Class.forName("java.lang.String"); Field[] fed = cls.getFields(); for(int i = 0;i<fed.length;i++) { System.out.println(fed[i]); } } }//输出结果:/*public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER*/
三、一个简单的例子:找出类的方法
有的时候,程序执行到某处的时候才会知道要调用某个方法,这里我们用反射来实现通过用户输入方法名来调用方法
package ex; import java.util.Scanner; import java.lang.reflect.*; public class Test { public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ System.out.println("What is your favourite color?"); Scanner sc = new Scanner(System.in); String color = sc.nextLine(); Class cls = Class.forName("ex.fruit"); //Class []para = new Class[2]; Method mtd = cls.getDeclaredMethod(color);//parameterTypes mtd.invoke(null); sc.close(); } } class fruit{ static void red() { System.out.println("You like red."); } static void blue() { System.out.println("You like blue."); } static void black() { System.out.println("You like black."); } static void white() { System.out.println("You like white."); } }//运行结果 /*What is your favourite color? *blue *You like blue. */
//这里只是为了用反射而用反射,几个例子都不是很好,打开API会发现这简直是新世界的大门
//如有错误,欢迎指正
- 【反射】JAVA反射机制
- 【Java】JAVA反射机制
- Java 反射机制[Field反射]
- Java 反射机制[Method反射]
- Java反射机制笔记-反射机制
- java的反射机制
- Java的反射机制
- java反射机制详解!
- Java反射机制
- Java的反射机制
- java 反射机制--侯捷
- java反射机制
- java反射机制
- [候捷]Java反射机制
- java 反射机制
- java 反射机制初探
- 关于Java反射机制
- java反射机制
- 一只爬虫带你看世界【1】
- 文件的读写代码块(二)
- 习题三3.2
- 10.23刷题记录
- 100019. 【NOI2017模拟6.26】A
- Java反射机制
- 为什么在java中不能创建泛型数组
- html上传文件
- 【安全牛学习笔记】CSRF跨站请求伪造攻击漏洞的原理及解决办法
- LeetCode Add Two Numbers
- UVa 133 The Dole Queue
- ROS小白碰壁记之4 读入地图
- free_low_memory_core_early
- 将一个正整数分解质因数