黑马程序员——反射

来源:互联网 发布:淘宝一元拍入口 编辑:程序博客网 时间:2024/05/16 13:54

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

反射

理解反射的概念

反射就是把Java类中的各种成分映射相成Java类。 例如:众多的人用一个Person类来表示,那么众多的Java类就用一个Class类来表示。 

Class类

Class类用于表示.class文件,是所有加载进内存的字节码对象的父类。所以可以通过Class得到运行时的类。  同一个类实例化的不同对象得到的字节码是同一个

注意:

1、int.class == Integer.TYPE。

2、数组类型的Class实例对象Class.isArray()为true。

3、反射并不是Java 5.0的新特性。

常用方法

System.out.println("判断int基本数据类型和Integer的基本数据类型" + "是不是同一个Class对象 结果为:"+(int.class == Integer.TYPE)); System.out.println("判断int.class是不是基本数据类型 结果为:"+int.class.isPrimitive());System.out.println("判断是不是数组类型 结果为:"+int[].class.isArray()); 

*构造方法的反射应用(Coustructor类)*

Constructor类的实例对象代表类的一个构造方法。

反射公共,私有和保护的构造方法:

反射公共的需要的方法是:getConstructor(); 反射私有的需要的方法是:getDeclaredConstructor(); 

Constructor对象代表一个构造方法,Constructor对象有的方法:得到构造方法名字,得到所属于的类,产生实例对象。

得到某个类空参数构造方法,例:Constructor constructor = Class.forName("java.lang.String").getConstructor();得到某个类所有的构造方法,例: Constructor [] constructors= Class.forName("java.lang.String").getConstructors(); 得到某一个带参数的构造方法,例:         Constructor constructor =Class.forName("java.lang.String").getConstructor(StringBuffer.class); 

利用构造方法创建实例对象:

通常方式:String instance = new String(new StringBuffer("黑马程序员")); 反射方式:String instance = (String)constructor.newInstance("黑马程序员"); 

调用获得的方法时要用到上面相同类型的实例对象

通过Class类中的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。

*成员变量的反射(Field类)*

Field类代表反射某个类中的一个成员变量。
注意访问权限的问题)也就是说,定义的是类对象,而非对象的对象。

代码示例

package com.itheima.study; public class Person {     public int age;     private int height;     public Person(int age,int height){         this.age=age;        this.height=height;     } } package com.itheima.study;import java.lang.reflect.Field;public class ReflectTest{     public static void main(String...args) throws Exception{         Person p = new Person(20,30);         Field fieldAge = p.getClass().getField("age");         System.out.println(fieldAge.get(p));     } } 
注意:如果类的某个成员变量的修饰符是private,那么直接通过getField方法获取Field类型的对象就会出现错误。那么直接通过getDeclaredField方法获取Field。 通过称之为暴力反射的方式解决,也就是使用setAccessible(true)使private类型的成员变量也可以被获取值。

练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”CSDN社区”通过反射改成”黑马论坛”。

package 遍历E盘;public class fanshe {    public String str1 = "CSDN社区";    public String str2 = "黑马程序员";    public String str3 = "啊苏打水";    @Override    public String toString() {        return str1 + "++" + str2 + "++" + str3;    }}package 遍历E盘;import java.lang.reflect.Field;public class fanshe1 {    public static void main(String[] args) throws Exception {        // TODO Auto-generated method stub        fanshe f = new fanshe();        changeStringValue(f);        System.out.println(f);    }    private static void changeStringValue(Object f) throws Exception, Exception {        // TODO Auto-generated method stub        Field[] ff= f.getClass().getFields();        for (Field i:ff) {            String s1=(String)i.get(f);//获取实例化对象所对应的字段值            String newValue = s1.replace("CSDN社区", "黑马论坛" );             i.set(f, newValue);//修改值        }    }}

成员方法的反射(Method类)

Method类代表某个类中的一个成员方法

得到类中的某一个方法:

例子Method charAt = Class.forName("java.lang.String").getMethod("charAt",调用方法:通常方式:System.out.println(str.charAt(1));反射方式:System.out.println(charAt.invoke(str, 1)); 

如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?

说明该Method对象对应的是一个静态方法! 

JDK1.4和JDK1.5的invoke方法的区别:

JDK1.4:public Object invoke(Object obj,Object[] args) JDK1.5:public Object invoke(Object obj,Object... args) 

目标:写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。

package com.itheima.day01; import java.lang.reflect.Method; public class ReflectTest { public static void main(String[] args) throws Exception {     Class clszz = Class.forName(args[0]);     Method main = clszz.getMethod("main", String[].class);     main.invoke(null,"黑马程序员","黑马论坛","CSDN社区"); } } 

*数组与Object的关系及其反射类型*

具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用; 非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。

Arrays.asList()方法处理int[]和String[]时的差异。

int[] arr =new int[] { 1, 2, 3 }; String[] str =newString[] {"黑马程序员", "黑马论坛", "CSDN社区" // 通过Arrays.asList方法打印出集合的内容 System.out.println(Arrays.asList(arr)); // 结果:[[I@62bc184] //原因是因为JDK1.4中为Arrays.asList(Object[] a),JDK1中//Arrays.asList(T... a)。  arr是int[]类型,JDK1.4中的asList方//法理不了,JDK1.5可以处理。但是JDK1.5将  //int数组整体作为一个参数进行处理。 // 因此最终结果就是将 int[]进行了封装,结果类型也就成了[[I。 System.out.println(Arrays.asList(str)); // 结果:[a, b, c] }; 
0 0
原创粉丝点击