黑马程序员_JAVA之反射
来源:互联网 发布:vm 网络上有重名 编辑:程序博客网 时间:2024/06/05 20:45
------- android培训、java培训、期待与您交流!----------
instanceof关键字:
用于判断某个对象所属类型
格式:
对象 instanceof 类名 (返回值为布尔类型)
代码实现:
package cn.itcast;public class Demo {public static void main(String[] args) {Animal a = new Animal();System.out.println(a instanceof Animal);System.out.println(a instanceof Cat);System.out.println("==========================================");Cat c = new Cat();System.out.println(c instanceof Animal);System.out.println(c instanceof Cat);System.out.println("==========================================");Animal ac = new Cat();System.out.println(ac instanceof Animal);System.out.println(ac instanceof Cat);}}package cn.itcast;public class Animal {}package cn.itcast;public class Cat extends Animal {}类加载器
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载:
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象。
连接:
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化:
就是我们以前讲过的初始化步骤
类的初始化时机:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器:
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
组成:
Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
System ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
反射
概述:
反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射技术:要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
反射的好处:大大的增强了程序的扩展性
获取字节码对象:
方式一:
Person p = new Person();
Class c = p.getClass();
通过对象获取字节码文件对象
方式二:
Class c2 = Person.class;
任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.
方式三:
Class c3 = Class.forName("全限定名");
将类名作为字符串传递给Class类中的静态方法forName即可。
public static Class forName(String className)throws ClassNotFoundException通过类名获取字节码文件对象
代码实现:
package cn.itcast;public class Demo2 {public static void main(String[] args) throws ClassNotFoundException {//通过对象获取字节码文件对象Animal animal = new Animal();Class clazz = animal.getClass();//任意数据类型都具备一个class静态属性,看上去要比第一种方式简单Class clazz2 = Animal.class;System.out.println(clazz2);//将类名作为字符串传递给Class类中的静态方法forName即可。Class clazz3 = Class.forName("cn.itcast.Animal");System.out.println(clazz3);}}
package cn.itcast;public class Animal {}package cn.itcast;public class Cat extends Animal {}构造方法反射的标准步骤:
public Constructor[] getConstructors()throws SecurityException获取该字节码文件对象的所有公共的构造方法
public Constructor[] getDeclaredConstructors()throws SecurityException获取该字节码文件对象的所有声明的构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException获取一个公共的构造
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException获取一个声明的构造
代码实现:
package cn.itcast;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class Demo3 {public static void main(String[] args) throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException,InvocationTargetException {Class clazz = Animal.class;Class clazz2 = new Animal().getClass();Class clazz3 = Class.forName("cn.itcast.Animal");// 获取Person的字节码文件对象Class clazz4 = Person.class;// 调用Class的方法,获取Person类的构造方法Constructor[] constructors = clazz4.getConstructors();for (Constructor constructor : constructors) {//System.out.println(constructor);}System.out.println("====================================================");Constructor[] declaredConstructors = clazz4.getDeclaredConstructors();for (Constructor constructor : declaredConstructors) {//System.out.println(constructor);}// 使用方法获取一个空参构造Constructor cfor0 = clazz4.getDeclaredConstructor();// 使用方法获取一个带三个参数的构造Constructor cfor3 = clazz4.getDeclaredConstructor(String.class,int.class, String.class);//跳过权限检查:暴力反射cfor3.setAccessible(true);// 使用对应的构造方法对象Object newInstance = cfor0.newInstance();System.out.println((Person)newInstance);Object newInstance2 = cfor3.newInstance("唐嫣",18,"女");Person p = (Person)newInstance2;System.out.println(p);System.out.println(p.age);}}反射普通方法
public Method[] getMethods() throws SecurityException 获取所有公共的方法,包括继承的方法
public Method[] getDeclaredMethods() throws SecurityException 获取所有声明的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
name:方法名称 parameterTypes:参数的类型
public Object invoke(Object obj, Object... args)throws IllegalAccessException,IllegalArgumentException,InvocationTargetException 执行方法
obj:我要执行哪个对象的方法 args:方法的参数
代码实现:
package cn.itcast;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Demo5 {public static void main(String[] args) throws NoSuchMethodException,SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 获取字节码文件对象Class clazz = Person.class;// 调用方法获取普通方法//Method[] methods = clazz.getMethods();//for (Method method : methods) {//System.out.println(method);//}//System.out.println("============================");//Method[] methods2 = clazz.getDeclaredMethods();//for (Method method : methods2) {//System.out.println(method);//}// 反射一个普通方法,空参,一个参数Method mfor0 = clazz.getDeclaredMethod("method2");Method mfor1 = clazz.getDeclaredMethod("method3", String.class);Method mforReturn = clazz.getDeclaredMethod("method");//使用方法Person p = new Person("唐嫣",18);Person p2 = new Person("诗诗",38);mfor0.invoke(p);//由于一个参数的方法是私有化方法,外界无法访问,所有需要暴力反射mfor1.setAccessible(true);mfor1.invoke(p2, "我被调用了");Object result = mforReturn.invoke(p);System.out.println(result);}}动态代理
代理者 代理 被代理者 执行方法
执行方法:本来是被代理者的方法,却被代理者代理执行了
这里的动态:
代理的方法是动态的。
JDK提供的代理只能针对接口做代理。
Proxy:代理类
创建动态代理类对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException通过该方法返回代理对象
InvocationHandler: 接口
用于定义如何代理
Object invoke(Object proxy,Method method,Object[] args)throws Throwable这个方法定义了代理类如何代理
proxy:代表代理对象,但是这里不使用!
method: 要被代理的方法 就是那个动态的方法
args:参数
代码实现:
package cn.itcast2;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Demo {public static void main(String[] args) {//被代理者Person p = new Person();//代理者:代理对象ClassLoader loader = p.getClass().getClassLoader();Class<?>[] interfaces = p.getClass().getInterfaces();//创建InvocationHandler对象InvocationHandler ih = new MyHandler(p);//代理对象Object object = Proxy.newProxyInstance(loader, interfaces, ih);Animal myProxy = (Animal)object;//通过代理对象调用方法myProxy.eat();myProxy.sleep(3);String sport = myProxy.sport();System.out.println(sport);}}package cn.itcast2;public interface Animal {//吃饭的方法void eat();//睡觉的方法void sleep(int times);//运动String sport();}package cn.itcast2;public class Person implements Animal {@Overridepublic void eat() {System.out.println("吃了");}@Overridepublic void sleep(int times) {System.out.println("一天睡"+times+"觉");}@Overridepublic String sport() {return "敲代码";}}package cn.itcast2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/* * 定义InvocationHandler的子类对象 * */public class MyHandler implements InvocationHandler {//定义成员变量,用来接收 被代理者Person p;public MyHandler(Person p) {this.p = p;}//该方法定义具体如何代理@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//添加一些其他的更强大的功能//验证这个动物是不是人,人才可以调用//通过反射的方式调用方法Object result = method.invoke(p, args);//添加一些其他的更强大的功能//返回方法返回值return result;}}
- 黑马程序员_JAVA之反射
- 黑马程序员_Java基础加强之反射
- 黑马程序员_Java高新技术之反射
- 黑马程序员_java基础加强之反射
- 黑马程序员_java高新之反射
- 黑马程序员_java高新技术之反射
- 黑马程序员_java高新技术之反射技术
- 黑马程序员_java高新之反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_java反射
- 黑马程序员_JAVA:反射
- 华为OJ--对称密码提取
- ACM-数据结构-并查集
- UILabel自适应高度
- mahout k-means聚类的入门操作步骤重点:
- Web
- 黑马程序员_JAVA之反射
- 单例模式 简单工厂模式
- mysql 随机更新表里的几条数据
- 我开通新的博客啦!
- 轻松几步,让Visual Stdio 2010 支持Html5
- ASP.NET-DataList控件-DataList嵌套
- 设计模式读书笔记:Mediator(中介者)
- LeetCode225:Implement Stack using Queues
- 多个文本文件两两碰撞相同内容