您的位置:首页 > 职场人生

黑马程序员_java基础_反射

2015-09-20 16:18 274 查看
------- android培训java培训、期待与您交流!---------
反射

一、概述
反射技术:
        Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
        简单一句话:反射技术可以对类进行解剖。

二、应用场景
        一个已经可以使用的应用程序,因为程序已经做好可以运行使用,不能再进行代码的加入了。而当后期我们新的功能加入程序时,该怎么做呢?就如我们的电脑一样,后期我们可能会鼠标、键盘等,所以电脑给我们预留了usb接口,只要符合这个接口规则的设备,电脑就可以通过加载驱动等操作来使用。

三、反射的基石——Class类
      1、所有的类文件都有共同属性,所以可以向上抽取,把这些共性内容封装成一个类,这个类就叫Class(描述字节码文件的对象)。
        Class类中就包含属性有field(字段)、method(方法)、construction(构造函数)。
        而field中有修饰符、类型、变量名等复杂的描述内容,因此也可以将字段封装称为一个对象。用来获取类中field的内容,这个对象的描述叫Field。同理方法和构造函数也被封装成对象Method、Constructor。要想对一个类进行内容的获取,必须要先获取该字节码文件的对象。该对象是Class类型。
        Class类描述的信息:类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表等。每一个字节码就是class的实例对象。如:class cls=Data.class;
    2、获取Class对象的三种方式
         a、通过对象的getClass方法进行获取。
              如:Class clazz=new Person().getClass();//Person是一个类名
             麻烦之处:每次都需要具体的类和该类的对象,以及调用getClass方法。
        b、任何数据类型都具备着一个静态的属性class,这个属性直接获取到该类型的对应Class对象。
             如:Class clazz=Person.class;//Person是一个类名
        c、这种方式较为简单,只要知道类的名称即可。就可以获取到Class对象了。
             如:Class clazz=Class.forName("包名.Person");//Person是一个类名
             这种方式仅知道类名就可以获取到该类字节码对象的方式,更有利于扩展。

四、Constructor类
     1、概述
          如果指定的类中没有空参数的构造函数,或者要创建的类对象需要通过指定的构造函数进行初始化。这时怎么办呢?这时就不能   使用Class类中的newInstance方法了。既然要通过指定的构造函数进行对象的初始化。就必须先获取这个构造函数        ——Constructor。Constructor代表某个类的构造方法。
     2、获取构造方法:
           1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
                Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();
          2)获取某一个构造方法:
               Constructor con= Class.forName(“cn.itheima.Person”).getConstructor(String.class,int.class);
    3、创建实例对象:
        Person p= (Person)con.newInstance(“lisi”,30);

五、Field类
     1、Field类代表某个类中一个成员变量
     2、方法
           Field getField(String s);//只能获取公有和父类中公有
           Field getDeclaredField(String s);//获取该类中任意成员变量,包括私有
           setAccessible(ture); //如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
           set(Object obj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
           get(Object obj);//返回指定对象上Field表示的字段的值。

五、Method类
     1、概述:Method类代表某
b222
个类中的一个成员方法。调用某个对象身上的方法,要先得到方法,再针对某个对象调用。
     2、专家模式:谁调用这个数据,就是谁在调用它的专家。

     3、方法
           Method[]  getMethods();//只获取公共和父类中的方法。
           Method[]  getDeclaredMethods();//获取本类中包含私有。
           Method   getMethod("方法名",参数.class(如果是空参可以写null));
           Object   invoke(Object obj ,参数);//调用方法
           如果方法是静态,invoke方法中的对象参数可以为null。
六、反射的作用——>实现框架的功能
     1、框架:通过反射调用Java类的一种方式。

     2、框架机器要解决的核心问题:
           我们在写框架(造房子的过程)的时候,调用的类(安装的门窗等)还未出现,那么,框架无法知道要被调用的类名,所以在程    序中无法直接new其某个类的实例对象,而要用反射来做。
      3、简单框架程序的步骤:
           1)右击项目File命名一个配置文件如:config.properties,然后写入配置信息。如键值对:className=java.util.ArrayList,等         号右边的配置键,右边是值。
          2)代码实现,加载此文件:
                ①将文件读取到读取流中,要写出配置文件的绝对路径。
                    如:InputStream is=new FileInputStream(“配置文件”);
                ②用Properties类的load()方法将流中的数据存入集合。
                ③关闭流:关闭的是读取流,因为流中的数据已经加载进内存。
          3)通过getProperty()方法获取className,即配置的值,也就是某个类名。
          4)用反射的方式,创建对象newInstance()。
          5)执行程序主体功能
Teacher1类调用Student类中的构造函数和方法的代码:
Student类的代码:

package duixiang;

public class Student {

private String name;
private int age;
Student(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public String toString(){
return name+":::"+age;
}
public void study(){
System.out.println("学生要学习");
}

}


配置文件:config.properties

文件内容:Name=duixiang.Student
Teacher1 的代码:

package duixiang;

import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;

public class Teacher1 {

public static void main(String[] args) {
try {
//将配置文件读取到流中
FileInputStream fis=new FileInputStream("config.properties");
//创建Properties对象
Properties pro=new Properties();
//将流中的数据存入到集合中
pro.load(fis);
//关闭流
fis.close();
//获取配置文件中的值
String property=pro.getProperty("Name");
//获取Class对象
Class<?> clazz=Class.forName(property);
//获取构造函数
Constructor<?> con=clazz.getDeclaredConstructor(String.class,int.class);
//创建实例对象
con.setAccessible(true);
Student stu=(Student)con.newInstance("zhangsan",34);
System.out.println(stu.toString());
stu.study();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}

}


------- android培训java培训、期待与您交流!---------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息