黑马程序员——java高新技术之反射

来源:互联网 发布:海岛奇兵导弹数据 编辑:程序博客网 时间:2024/05/10 20:25
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、什么是反射

反射就是将java程序类的各个要素(成员变量、构造方法、方法、包)映射成对应的类。
二、Class类概述

反射的基石是Class类,下面用一个比喻来说明什么是Class类。小明、小红、小强都属于Person类,小狗、小猫、小鸟都属于Animal类,按照java万物皆对象的理论,那Person类和Animal类本身也是对象,这两个对象从属于哪个类?不错,它们都属于Class类。Class类就是用来描述java程序中的各个类的一类事物,该类的实例化对象就是java程序中的各个类(或者说是各个类的字节码文件)。

Class实例化的三种方式:1. Class cls = Person().getClass();;  2.Class cls = Class.forName("包名.类名"); 3.Class cls = Person.class;

九个预定义的Class实例化对象: (byte short int long float double char boolean void ).class      即基本数据类型加上void的字节码文件。

注意:基本数据类型的字节码文件都可以用与之对应的包装类中的TYPE常量表示,int.class==Integer.TYPE  

三、Class中的方法
//Class中的方法forName()//静态方法,实例化时候使用getConstructor() //获取Class对象所表示的类中的某个构造方法,具体是哪个靠传参数确定getField() //获取Class对象所表示的类中的某个字段(成员变量),具体是那个靠传参数确定getMethod() //获取Class对象所表示的类中的某个方法,具体是哪个方法靠传参数确定getName() //获取Class对象所表示的类的名称getSuperClass()  //获取Class对象所表示的类的超类的名称isArray() //判断Class对象是否表示一个数组isPrimitive() //判断Class对象是否是一个基本数据类型newInstance() //创建Class对象所表示的类的一个实例对象,返回类型为泛型,使用时需强转

四、Constructor类及其应用
//Constructor类及其应用Constructor是用来描述构造方法的类,那么它用在什么地方呢?Class对象通过newInstance()可以创建一个不附带任何属性的类对象,当我们需要创建一个附带属性的类对象时,就需要使用Constructor来完成。该类常用方法:getConstructors()  getConstructor()Constructor con = Class.forName("类名.包名").getConstructor(String.class,int.class);Person p = (Person)con.newInstance("lisi",21);

五、Field类及其应用
//Field类及其应用Field是用来描述成员变量的类,该类的常用方法有:get() set() setAccessible(true)其使用场景如下述代码。        class Person{publicString name;private int age;Person(String name,int age){this.name= name ;this.age = age ;}}Field f = Person.class.getField("name");//getField不能得到private修饰的成员变量Field f2 = Person.class.getDeclaredField("age");//getField可以得到私有成员变量Person p = new Person("lisi",20);f2.get(p); //得到的是p的age=20f2.setAccessible(true);//暴力访问私有变量f2.set(p, 30); //改变P对象的age字段为30f2.get(p); //得到的是p的age=30

六、Method类及其应用
//Method类及其应用Method是用来描述成员方法的一个类,该类的常用方法:invoke()。其应用场景如下述代码所示。//声明一个Person类class Person{publicString name;private int age;Person(String name,int age){this.name= name ;this.age = age ;}public void run(int time){System.out.prinln("跑"+time+"分钟");}}//使用Method类Method m = Person.class.getMethod("run", int.class);//通过反射得到Person类的run方法Person p = new Person("lisi",40);m.invoke(p, 15); //p调用m方法并将15作为参数传给m方法注:当m所表示的方法为静态方法时,可写作m.invoke(null,参数)

七、数组反射

数组反射用的的是Array类,该类主要方法有:getLength(Object obj)  和get (obj , int x) 。。前者用于获取数组长度,后者用于获取数组中的元素。练习如下。
//需求:通过反射机制打印数组的每一个元素class ArrayReflect{public static void main(String[] args){int[] arr = new int[]{1,2,3,4};}//封装一个打印方法public static print(Object obj){Class cls = obj.getClass();//先判断要打印的对象是否为数组,如果是,遍历数组并打印if(cls.isArray()){int len = Array.getLength(obj);for(int x=0;x<len;x++){System.out.println(Array.get(obj, x));}}else{ //如果不是,直接打印System.out.println(obj);}}}

八、框架
所谓框架,用一个形象的比喻来说明。我们都知道房屋建成后,不能直接被我们入住使用,我们需要给房子装上门窗并做一些刷墙和添置家具等动作后,才能住进去。在这个例子中,房子就是框架,而门窗家具和刷墙等是实现房子框架提前定好的规则之后被我们加进去的。总之,房子就是框架,门窗家具等都是后期加入的类。
/* * 需求:写一个简单的框架程序,可以接收后期用户提供的类 * 思路: * 1.创建一个Properties集合用来获取配置文件数据 * 2.创建一个字节读取流,这个流需要关联到配置文件 * 3.用户提供的类名以className="XXXX"的格式存到配置文件中 * 4.通过Properties得到getProperty方法拿到用户传入的类名"" */ package com.itheima;import java.io.FileInputStream;import java.io.InputStream;import java.util.Collection;import java.util.Properties;class Demo{public static void main(String[] args) throws Exception{Properties prop = new Properties();//利用Class对象的getResourceAsStream得到一个关联着配置文件的字节输入流InputStream is = Demo.class.getResourceAsStream("config.properties");props.load(is);//将配置文件的数据加载进内存is.close();//利用getProperty方法获取用户提供的类名String className = prop.getProperty("className");Class clazz = Class.forName(className);}}

九、练习题
package cn.itheima.test;import java.io.File;import java.io.FileInputStream;import java.util.Properties;public class ReflectTest {public static void main(String[] args) throws Exception{/* *笔记本电脑使用usb设备  */ NoteBook computer=new NoteBook();computer.run();//关联配置文件File file=new File("usb.properties");FileInputStream fis=new FileInputStream(file);//将配置文件信息缓存到集合中Properties ps=new Properties();ps.load(fis);//System.out.println(ps.size());for(int x=1;x<=ps.size();x++){String className=ps.getProperty("usb"+x);//获取配置文件中类名Class clazz=Class.forName(className);//获取类的Class对象USB usb=(USB)clazz.newInstance();//得到类实例computer.useUSB(usb);//开始使用}fis.close();//关流}}//USB 接口public interface USB {void open();void close();}//笔记本电脑public class NoteBook {public void run(){System.out.println("NoteBook is run");}public void useUSB(USB usb){if(usb!=null){usb.open();usb.close();}}}//鼠标public class MouseUSB implements USB {@Overridepublic void open() {System.out.println("Mouse is use");}@Overridepublic void close() {System.out.println("Mouse is close");}}//键盘public class KeyUSB implements USB {@Overridepublic void open() {System.out.println("Key is use");}@Overridepublic void close() {System.out.println("Key is close");}}
0 0
原创粉丝点击