------- android培训、java培训、期待与您交流! ----------
java反射机制
Class类
java中用类来描述现实中的事物,描述某一类型事物拥有的属性和行为。java中的类也有一些特征,比如,类名,包名,属性,方法等,按照面向对象的思想,java中的类也可以用类来描述这些特征,Class类就是描述类这类事物的,Class类的对象就是字节码文件即类文件。
如何获取Class类的对象呢?
有三种方式:
1、Class cls1 = obj.getClass;
通过类的对象获取该类的字节码文件对象
所有的对象都具备getClass方法,而对象是由字节码文件加载进内存后创建的,可以通过对象调用getClass方法获取创建该对象的字节码文件。这种方式必须创建对象才能使用。
2、Class cls2 = 类名.class;
文件对象。这种方式需要在使用时就必须明确具体的类,也就是必须写进源程序。
3、Class cls3 = Class.forName( “classname”);
通过Class的静态forName ( )方法获取字节码文件。这种方式只需要知道类名即可,可以动态地获取配置文件中的类的字节码文件。
所有的数据类型都有对应的字节码文件
1、八种基本类型(byte、short、int、long、float、double、char、boolean)的字节码对象和一种返回值为void类型的void.class。Integer.TYPE是Integer类的一个常量,它代表此包装类型包装的基本类型的字节码,所以和int.class是相等的。基本数据类型的字节码都可以用与之对应的包装类中的TYPE常量表示
2、数组类型的Class实例对象,如int[].class,可以用Class.isArray()方法判断是否为数组类型的。
Class类中的方法
static Class forName(String className)
返回与给定字符串名的类或接口的相关联的Class对象。
Class getClass()
返回的是Object运行时的类,即返回Class对象即字节码对象
Constructor getConstructor()
返回Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。
Field getField(String name)
返回一个Field对象,它表示此Class对象所代表的类或接口的指定公共成员字段。
Field[] getFields()
返回包含某些Field对象的数组,表示所代表类中的成员字段。
Method getMethod(String name,Class… parameterTypes)
返回一个Method对象,它表示的是此Class对象所代表的类的指定公共成员方法。
Method[] getMehtods()
返回一个包含某些Method对象的数组,是所代表的的类中的公共成员方法。
String getName()
以String形式返回此Class对象所表示的实体名称。
String getSuperclass()
返回此Class所表示的类的超类的名称
boolean isArray()
判定此Class对象是否表示一个数组
boolean isPrimitive()
判断指定的Class对象是否是一个基本类型。
T newInstance()
创建此Class对象所表示的类的一个新实例。
反射机制
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单来说就是,反射可以对类进行解剖,将组成类的各种成分映射成对象。
反射的好处:大大提高了程序的扩展性。
使用反射的步骤:
1、获取Class对象
2、获取类的属性、方法或构造函数。
3、访问属性、调用方法,调用构造函数创建对象。
反射的应用
1、成员变量的反射
首先获取指定类的字节码文件对象
Class clazz1 = Class.forName(“classname”);
获取字节码文件的成员变量对象
Field field = clazz.getField(fieldName);
对成员变量操作
field.setAccessible(true);设置字节码文件的实例对象的私有属性可访问,即暴力反射
field.setObject(value);设置字节码文件的实例对象的属性值
class Student { private String name; public int age; public Student(String name, int age) { this.name = name; this.age = age; } } class FieldDemo { public static void main(String[] args) throws Exception { Student zs = new Student("zhangsan", 23); Field fieldAge = zs.getClass().getField("age"); System.out.println((fieldAge.get(zs))); Field fieldName = zs.getClass().getDeclaredField("name");// 可以得到私有的变量 fieldName.setAccessible(true); // 设置为可以访问 System.out.println((fieldName.get(zs))); } }
2、成员方法的反射
获取指定类的字节码文件对象
Class clazz2 = Class.forName(“classname”);
获取字节码文件的成员方法
Method method= clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});
调用该字节码文件的实例对象的方法
method.invoke();
class Person { private String name; public int age; public Person() { System.out.println("Person is run"); } public Person(String name, int age) { this.age = age; this.name = name; } } // 获取Person类中的方法 class MethodDemo { public void getPersonMethod() throws Exception { // 如果想要获取方法,必须先要有对象。 Class clazz = Class.forName("cn.itheima.Person"); Person p = (Person) clazz.newInstance(); // 获取所以方法 Method[] mes = clazz.getMethods();// 只获取公共的和父类中的。 // mes=clazz.getDeclaredMethods();//获取本类中包含私有。 for (Method me : mes) { System.out.println(me); } // 获取单个方法 Method me = clazz.getMethod("toString", null); Object returnVaule = me.invoke(p, null); System.out.println(returnVaule); } }
3、构造函数的反射
获取指定类的字节码文件对象
Class clazz3 = Class.forName(“classname”);
获取字节码文件的构造方法
Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...})
通过构造方法创建指定类的实例对象
con.newInstance(params...)
class Person { private String name; public int age; public Person() { System.out.println("Person is run"); } public Person(String name, int age) { this.age = age; this.name = name; } } class ConstructorDemo { public static void createPersonClass_2() throws Exception { // 获取Person类的Class对象 String className = "cn.itheima.Person"; Class clazz = Class.forName(className); // Class clazz=Person.class; // 获取指定构造函数的类实例 Constructor con = clazz.getConstructor(String.class, int.class); Person p = (Person) con.newInstance("lisi", 30); System.out.println(p.toString()); } }
4、数组的反射
框架的概念及用反射技术开发框架的原理具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
Object[]与String[]没有父子关系,Object与String有父子关系,所以new Object[]{“aaa”,”bb”}不能强制转换成new String[]{“aaa”,”bb”}; Object x =“abc”能强制转换成String x =“abc”
Array工具类用于完成对数组的反射操作。
Array.getLength(Object obj);//获取数组的长度
Array.get(Object obj,int x);//获取数组中的元素
什么是框架?
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序呢?我写的框架程序怎样能调用到你以后写的类(门窗)呢?因为在写才程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象了,而要用反射方式来做。

445

被折叠的 条评论
为什么被折叠?



