A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© matthewjk 中级黑马   /  2015-4-6 18:29  /  548 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1:反射

        (1)类的加载及类加载器
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象。
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
类加载器的组成
Bootstrap ClassLoader 根类加载器,也被称为引导类加载器,负责Java核心类的加载

Extension ClassLoader 扩展类加载器,负责JRE的扩展目录中jar包的加载。
Sysetm ClassLoader 系统类加载器,负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径




反射:
                通过字节码文件对象,去使用成员变量,构造方法,成员方法
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
获取构造方法
                getConstructors
                getDeclaredConstructors
创建对象
                newInstance() 创建此 Class 对象所表示的类的一个新实例。
                con.newInstance(“zhangsan", 20);

获取所有成员
                getFields,getDeclaredFields
获取单个成员
                getField,getDeclaredField
修改成员的值
                set(Object obj,Object value) ???将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
获取所有方法
                getMethods
                getDeclaredMethods
获取单个方法
                getMethod
                getDeclaredMethod
暴力访问
                method.setAccessible(true);
Object invoke(Object proxy,
              Method method,
              Object[] args)
              throws Throwable在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

        (3)反射的使用
                A:通过反射获取构造方法并使用
                B:通过反射获取成员变量并使用
                C:通过反射获取成员方法并使用
/*1、 ArrayList<Integer> list = new ArrayList<Integer>(); 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
* */
package com.itheima;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Test1 {

        public static void main(String[] args) throws IllegalAccessException,
                        IllegalArgumentException, InvocationTargetException,
                        NoSuchMethodException, SecurityException {
                ArrayList<Integer> list = new ArrayList<Integer>();
                Class c = list.getClass();// 集合ArrayList的class文件对象
                Method m = c.getMethod("add", Object.class);
                m.invoke(list, "qwe");// 调用list的add方法,传入值一个字符串对象

                System.out.println(list);

        }

}

        (4)反射案例
                A:通过反射运行配置文件的内容
                B:通过反射越过泛型检查
                C:通过反射给任意的一个对象的任意的属性赋值为指定的值
        (5)动态代理:其实就是通过反射来产生一个代理。
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
案例
//创建接口
public interface UserDao {
        public abstract void add();
        public abstract void delete();
        public abstract void update();
        public abstract void find();
}
//创建类实现接口
public class UserDaoImpl  implements UserDao{

        @Override
        public void add() {
                System.out.println("添加功能");
               
        }

        @Override
        public void delete() {
                System.out.println("删除功能");
               
        }

        @Override
        public void update() {
                System.out.println("更新功能");
               
        }

        @Override
        public void find() {
                System.out.println("查找功能");
        }

}
//创建类实现InvocationHandler接口,重写invoke()方法
public class MyInvocationHandler implements InvocationHandler {
       
        private Object target;

        public MyInvocationHandler(Object target) {
               
                this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
System.out.println("权限校验");
Object result=method.invoke(target, args);
System.out.println("日志记录");
                return result;
        }
       
       

}


public class InvocationTest {

        public static void main(String[] args) {
               //创建目标对象
                UserDao ud=new UserDaoImpl();
                //对ud对象做一个代理对象
                MyInvocationHandler handler=new MyInvocationHandler(ud);
                UserDao proxy=(UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler);
                proxy.add();
                proxy.delete();
                proxy.find();
                proxy.update();
        }

}
案列:通过配置文件运行类中的方法
package cn.itcast.heima;

public class DemoClass {
        public void run()
    {
       System.out.println("welcome to heima!");
    }   

}
配置文件(知道有那几个键)
className=cn.itcast.heima.DemoClass
methodName= run
程序:
ackage com.itheima;

import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/*Properties格式的配置文件在JRE系统库下*/
public class Test7 {

        public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
                //加载键值对数据
                Properties prop=new Properties();
                FileReader fr=new FileReader("Test7.txt");
                prop.load(fr);
                fr.close();
                //获取数据
        String className=prop.getProperty("className");
        String methodName=prop.getProperty("methodName");
        //反射
        Class c=Class.forName(className);
        Constructor con=c.getConstructor();
        Object obj=con.newInstance();
        Method m=c.getMethod(methodName);
        m.invoke(obj);
        


        }
       

}

       

1 个回复

倒序浏览
不调戏,这不叫笔记吧?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马