java基础————java高新技术之反射

来源:互联网 发布:淘宝怎么做排名靠前 编辑:程序博客网 时间:2024/05/17 00:05


反射

反射机制概述:

JAVA反射机制是在运行转态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息

以及动态调用对象的方法的功能称为java语言的反射机制。简单一句话:反射技术可以对一个类进行解剖。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。

Class类——反射的基石:

java中所有的类文件都有共性的内容,可以进行向上抽取,把这些共性内容用类进行封装,这个类就是Class。Class类封装了java类中定义的成员变量,成员方法,构造函数等。

获取Class对象的三种方式:

1:通过对象的getClass()方法获取(每个class都有此方法)

示例:

String str = "abc";

Class c = str.getClass();

2:任何数据类型都有一个静态的属性class,这个属性可以直接获取到该类的Class对象。

示例:

Class c = String.class;

3:使用Class类中的静态方法forName();

示例:

Class c = Class.froName("java.lang.String");

这种方法这样知道类名称就可以获取字节码文件,不需要使用该类,也不需要去调用该类具体的方法和属性,所以更有利于程序的扩展。

九个预定义Calss的示例对象:

1:八种基本数据类型(byte,short,int,long,float,double,char,boolean)字节码对象和一种返回值为空void类型的void.class。

2:Integer.TYPE是Integer类的一个常量,它代表此包装类型包装的基本类型的字节码,所以和ing.class是相等的。基本数据类型的字节码都可以用与之对应的包装类中

的TYPE常量表示。

isPrimitive()方法可以判断是否是基本数据类型的字节码。

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对象所表示的类的一个新实例。

Constructor:

如果指定的类中没有空参数的构造函数,或者要创建的类对象需要通过指定的构造函数进行初始化。这时怎么办呢?这时就不能使用Class类中的

newInstance方法了。既然要通过指定的构造函数进行对象的初始化。就必须先获取这个构造函数——ConstructorConstructor代表某个类的构造方法。

获取构造方法:

得到这个类的所有构造方法:以Student类为例

   Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();

获取某一个构造方法:

      Constructor con=Person.class.getConstructor(String.class,int.class);

创建实例对象:

        通常方式:Person p = new Person(“lisi”,30);

        反射方式:Person p= (Person)con.newInstance(“lisi”,30);

Filed类:

Filed类代表某个类中的一个成员变量。

常用方法:

Field getField(String s);

只能获取公有和父类中公有变量

Field getDeclaredField(String s);

获取该类中任意成员变量,包括私有

setAccessible(ture);

如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。

set(Object obj, Object value);

将指定对象变量上此Field对象表示的字段设置为指定的新值。

Object get(Object obj);

返回指定对象上Field表示的字段的值。

下面通过一段代码演示一下Filed的常用方法:

<span style="font-size:12px;">package com.heima.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import com.heima.bean.Person;public class Demo4_Field {public static void main(String[] args) throws Exception {Class clazz = Class.forName("com.heima.bean.Person");Constructor c = clazz.getConstructor(String.class,int.class);//获取有参构造Person p = (Person) c.newInstance("张三",23);//通过有参构造创建对象//Field f = clazz.getField("name");//获取姓名字段//f.set(p, "李四");//修改姓名的值Field f = clazz.getDeclaredField("name");//暴力反射获取字段f.setAccessible(true);//去除私有权限f.set(p, "李四");System.out.println(p);}}</span>


Method类:

Method类代表某个类中的一个成员方法。调用某个对象身上的方法,要先得到方法,再针对某个对象调用。

常用方法:

Method[] getMethods();

只获取公共和父类中的方法。

Method[] getDeclaredMethods();

获取本类中包含私有。

Method   getMethod("方法名",参数.class(如果是空参可以写null);

Object invoke(Object obj ,参数);调用方法

如果方法是静态,invoke方法中的对象参数可以为null

下面通过一段代码演示Method类的常用方法

<span style="font-size:12px;">package com.heima.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import com.heima.bean.Person;public class Demo5_Method {public static void main(String[] args) throws Exception {Class clazz = Class.forName("com.heima.bean.Person");Constructor c = clazz.getConstructor(String.class,int.class);//获取有参构造Person p = (Person) c.newInstance("张三",23);//通过有参构造创建对象Method m = clazz.getMethod("eat");//获取eat方法m.invoke(p);Method m2 = clazz.getMethod("eat", int.class);//获取有参的eat方法m2.invoke(p, 10);}}</span>

数组的反射: 

1;具有相同类型和相同维数的数组共享同一份字节码,即同一个Class类。

2;代表数组的Class实例对象的getSupperClass()方法返回的父类为Object类对应的Class。

3;基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,即可以做Object类型使用,又可以当作Object[]类型使用。

4;Array.asList()方法处理int[]和String[]的时候是有差异的;

例如:

用Array中的asList()方法处理String[]:

Arrays.asList(new String[] {"aa", "bb", "cc"});转换后的List集合里面有3个元素,分别是"aa", "bb", "cc";

用Array中的asList()方法处理int[]:

Arrays.asList(new int[] {1, 2, 3});转换后的List集合里面就只有一个元素,这个元素就是new int[] {1, 5, 9}这个数组本身。

5;Array工具类用于完成数组的反射操作,类里面的方法都是静态的;

如以下代码:

<span style="font-size:12px;">public void printObject(Object obj) {    if(obj.getClass().isArray()) {        for(int i = 0; i < Array.getLength(obj); i++){System.out.println(Array.get(obj, i));        }    }     else     {        System.out.println(obj);    }}</span>


 


 

 

 

 

 

0 0
原创粉丝点击