`
AlexShaw
  • 浏览: 12890 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java学习日记_Java高新技术_反射

阅读更多

---------------------- android培训java培训java学习型技术博客、期待与您交流! ----------------------

关于java反射

Class 用于描述java类的类,java程序的各个类属于同一个事物,而Class就是用来描述这个事物的,通过Class可以得到这个类方方面面的信息

Class clz = new Class();//错误,代表内存里面的一份字节码

字节码:当我们在语言程序中用到了某个类时,首先从硬盘上编译的二进制字节码内存加载到内存中,然后用这些字节码创建对象,这份字节码就是一个对象,这个对象的类型就是Class.forName()的作用就是返回字节码,返回的方式有两种,一直是这份字节码已经在虚拟机中,另一种是从硬盘上寻找

    a d1 = new a();

    a d2 = new a();

    Class c1 = d1.getClass();

    Class c2 = void.class;

    //得到a这个类的字节码

    //得到字节码有三种方式,对象.getClass或者类.class或者Class.forName

spring或者hibernate的配置文件中,通过在XML文件中定义某个类的名字,其实就是通过Class.forName方式将某个class文件或者字节码加载到内存中

八个基本类型对应8个基本的实例对象 void其实也有对应一个实例对象

只要是在源程序中出现的类型都有对应的class实例对象int[]void

try {

           String str = "";

           Class c1 = str.getClass();

           Class c2 = String.class;

           Class c3 = Class.forName("java.lang.String");

           //每一个类只会加载一份字节码

           System.out.println(c1 == c2);

           //是否是基本类型

           System.out.println(c1.isPrimitive());

           System.out.println(int.class.isPrimitive());

           System.out.println(int.class == Integer.class);

           //Integer.TYPE表示它所包装的基本类型

           //数组类型不是基本类型,判断是否是数组类型要用isArray

           System.out.println(int.class == Integer.TYPE);

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       }

反射:反射就是把类中的各个部分映射响应的java类,把java中的每一个部分映射成对应的类

Constructor代表某个类的构造方法

创建构造方法时候定义的构造方法的参数的个数,类型,顺序要和调用构造方法是的参数的个数,类型,顺序相匹配

//java中的构造方法没有顺序

       //要调用哪个方法需要在getConstructor方法里带上参数类型

       Constructor cs = Class.forName("java.lang.String")

       .getConstructor(String.class);

       //获得这个类

       System.out.println(cs.getName());

       //通过构造方法构造实例对象

       //newInstance

       System.out.println(cs.newInstance("aa"));

Class.newInstance:首先得到默认的构造方法然后创建对象,用缓存机制来保存默认构造方法的实例对象

Field:如果类中某个属性为私有则需要通过暴力反射来获取如下代码

publicclass Reflect {

/**

     * @title main

     * @descriptionTODO

     * @author Alex Shaw

     * @create_date 2013-3-15

     * @param args

     * @throws NoSuchFieldException

     * @throws SecurityException

     * @throws IllegalAccessException

     * @throws IllegalArgumentException

     */

    publicstaticvoid main(String[] args) throws SecurityException, IllegalArgumentException, IllegalAccessException {

       try {

           Field1 f = new Field1(3,4);

           Field c = f.getClass().getField("a");

           //c只是代表这个类字节码身上的变量,没有对应到对象身上

           //所以要把这个对象穿进去

           //想要取出某个属性,则这个属性必须非私有(可见的)

           //如果想要访问私有变量,通过下面的方法

           Field d = f.getClass().getDeclaredField("b");

           //通过上面代码无法访问b

           d.setAccessible(true);//暴力反射

           System.out.println(c.get(f));

           System.out.println(d.get(f));

       } catch (NoSuchFieldException e) {

           e.printStackTrace();

       }

    }

}

class Field1 {

    publicinta;

    privateintb;

    public Field1(int a, int b) {

       super();

       this.a = a;

       this.b = b;

    }

}

练习:将任意对象中的String类型变量的值B改成A

字节码的比较用== 因为都是那一份

publicvoid reflect(Object obj) throws IllegalArgumentException, IllegalAccessException

    {

       //获取属性数组

       Field[] fields = obj.getClass().getFields();

       for(Field field :fields)

       {

           //获取属性名为A的属性

           String oldstr = (String)field.get("A");

           String newstr = oldstr.replace('A', 'B');

           //将修改后的字符串赋值给A

           field.set("A", newstr);

       }

    }

Method:通过反射获取类的方法

方法与对象是没有关系的,它是属于这个类的,先得到这个方法,然后针对某个对象去调用这个方法

通过反射的方式获取字节码中的方法,再用这个方法作用与某个对象

专家模式:

JDK1.41.5的区别,1.4没有可变参数,只能把参数封装成一个数组

数组的反射

具有相同维数和类型的数组属于同一个类型,对应着同一份字节码文件,具有相同的class实例对象

通过反射获取数组,无法知道数组的具体类型,只能获取数组中具体元素的具体类型

    /**

     *

     * @title toStringArray

     * @description通过反射遍历数组

     * @author Alex Shaw

     * @create_date 2013-3-16

     * @param obj

     * @throws IllegalArgumentException

     * @throws IllegalAccessException

     * @throws SecurityException

     * @throws NoSuchFieldException

     */

    publicstaticvoid toStringArray(Object obj) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException{

       if(obj.getClass().isArray())

       {

           //获取数组长度

           int length = Array.getLength(obj);

           //遍历

           for(int i = 0 ; i < length ; i++)

           {

              //通过get方法得到数组的每个元素

              System.out.println(Array.get(obj, i));

           }

       }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics