反射

一、反射的概述通过得到class对象后再得到类的信息

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象. 

 

以上的总结就是什么是反射

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

     (其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

如图是类的正常加载过程:反射的原理在与class对象。

熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

 

 

其中这个Class对象很特殊。我们先了解一下这个Class类





二、反射的使用(这里使用Student类做演示)

先写一个Student类。

class Student{
    private  String name = "caocao";
    public int age = 18;
    
    public Student(){
        System.out.println("Student.init!!");
    }
    
    public void fun1(){
        System.out.println("public  Student.fun1()!!");
    }
    
    private void fun2(){
        System.out.println("private Student.fun2()!!");
    }
}

 


1、获取Class对象的三种方式

1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性   直接通过“类名、class”方法
1.3 通过Class类的静态方法:forName(String  className)(常用)

 

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
        Student s1 = new Student();
        //1.s1.getClass()     
        Class c1 = s1.getClass();
        //2.直接通过 类名.class 安全可靠
        //说明任何一个类都有一个隐含的静态成员变量 class
        Class c2 = Student.class;
        //通过 Class 对象的 forName() 静态方法来获取
        //可能要抛出异常ClassNotFoundException
        Class c3 = Class.forName("com.tulun.src.Student");
        
        //一个类型         对应一个Class对象---》类型一一对应的
        /*System.out.println(c1==c3);
        System.out.println(c1==c2);
        System.out.println(c3==c2);*/

上面三种方法的得到是一个对象。。

那么如何通过class对象来得到类的信息呢??

有这么些方法:

 

        getName():获得类的完整名字。
  getFields():获得类的public类型的属性。
  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
  getMethods():获得类的public类型的方法。
  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,
       parameterTypes 参数指定方法的参数类型。
  getConstructors():获得类的public类型的构造方法。
  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
  newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

//1/ getName():获得类的完整路劲com.tulun.src.Student
        String classname = c1.getName();
        System.out.println(classname);
        //2、获得类的所有属性  包括私有成员变量
        //                Field[]    
        Field[] fileds2 = c1.getDeclaredFields();
        for(Field field : fileds2){
            System.out.println(field.getName());
        }
        System.out.println("======");
        
        //3、获得类内所有的方法         Method[]
        Method[] methonds = c1.getDeclaredMethods();
        for(Method methond : methonds){
            System.out.println(methond.getName());
        }
        
        //4.getConstructors():获得类的public类型的构造方法
        //                      Constructor[]
        Constructor[] conArray = c1.getConstructors();  
        for(Constructor c : conArray){  
            System.out.println(c);  
        }

 反射的缺点  ————缺乏安全性(通过反射能获取到private的属性,可以更改)

//     不安全之处
        //获取      private私有属性
        /*Field f2 = c1.getDeclaredField("name");//抛出异常
        System.out.println(f2);
        f2.setAccessible(true);//变为false后下面就不可以改变name的值了
        //设置可见性
        System.out.println("======");
        //不安全之处,通过获得一个这个类的对象
         Object p2 =  c1.newInstance();//抛出异常
         f2.set(p2,"高博");
         System.out.println(f2.get(p2));*/

 

posted on 2018-05-26 18:16  番茄疯了  阅读(111)  评论(0)    收藏  举报