反射?

类的加载过程:

1.如何创建Class的实例(重点)

1.1过程:源文件经过编译(javac.exe)以后,得到一个或多个.class文件。.class文件经过运行(java.exe)这步,
就需要进行类的加载(通过JVM的类的加载器),记载到内存中的缓存。每一个放入缓存中的.class文件就是一个Class的实例!

1.2 Class的一个对象,对应着一个运行时类。相当于一个运行时类本身充当了Class的一个实例。

1.3 java.lang.Class是反射的源头。 接下来涉及到反射的类都在java.lang.reflect子包下。如:Field Method Constructor Type Package..
当通过Class的实例调用getMethods() —>Method , getConstructors() —->Constructor

1.4实例化Class的方法(三种):

        // 1.调用运行时类的.class属性Class clazz1 = Person.class;System.out.println(clazz1);Class clazz2 = Creator.class;System.out.println(clazz2);// 2.通过运行时类的对象,调用其getClass()方法Person p = new Person();Class clazz3 = p.getClass();System.out.println(clazz3);// 3.调用Class的静态方法forName(String className)。此方法报ClassNotFoundExceptionString className = "com.atguigu.java.Person";Class clazz4 = Class.forName(className);System.out.println(clazz4);

2.Class的实例–应用一

应用一:可以创建对应的运行时类的对象(重点)

    //获取运行时类的对象:方法一@Testpublic void test1() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;System.out.println(a);}//调用指定的构造器创建运行时类的对象@Testpublic void test2() throws Exception{Class clazz = Animal.class;Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);cons.setAccessible(true);Animal a = (Animal)cons.newInstance("Tom",10);System.out.println(a);}

3.Class的实例–应用二

应用二:获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。

如:Method[] m1 = clazz.getMethods() :获取到对应的运行时类中声明的权限为public的方法(包含其父类中的声明的public)
Method[] m2 = clazz.getDeclaredMethods():获取到对应的运行时类中声明的所有的方法(①任何权限修饰符修饰的都能获取②不含父类中的)

4.Class的实例–应用三

应用三:调用对应的运行时类中指定的结构(某个指定的属性、方法、构造器)(重点)

//调用指定属性
@Test
public void test3() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;//调用非public的属性Field f1 = clazz.getDeclaredField("name");f1.setAccessible(true);f1.set(a, "Jerry");//调用public的属性Field f2 = clazz.getField("age");f2.set(a, 9);System.out.println(f2.get(a));System.out.println(a);//调用static的属性Field f3 = clazz.getDeclaredField("desc");System.out.println(f3.get(null));
}//调用指定的方法
@Test
public void test4() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;//调用非public的方法Method m1 = clazz.getDeclaredMethod("getAge");m1.setAccessible(true);int age = (Integer)m1.invoke(a);System.out.println(age);//调用public的方法Method m2 = clazz.getMethod("show", String.class);Object returnVal = m2.invoke(a,"金毛");System.out.println(returnVal);//调用static的方法Method m3 = clazz.getDeclaredMethod("info");m3.setAccessible(true);
//      m3.invoke(Animal.class);m3.invoke(null);
}

5.动态代理—反射的应用

体会反射的动态性
代理设计模式的原理:

使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时
将方法调用转到原始对象上

静态代理:要求被代理类和代理类同时实现相应的一套接口;通过代理类的对象调用重写接口的方法时,实际上执行的是被代理类的同样的
方法的调用。
静态代理模式

//静态代理模式
//接口
interface ClothFactory {void productCloth();
}// 被代理类
class NikeColthFactory implements ClothFactory {@Overridepublic void productCloth() {System.out.println("Nike工厂生产了一批衣服");}
}// 代理类
class ProxFactory implements ClothFactory {ClothFactory cf;public ProxFactory(ClothFactory cf) {this.cf = cf;}@Overridepublic void productCloth() {System.out.println("代理类开始执行,收代理费$1000");cf.productCloth();}
}public class TestClothProduct {public static void main(String[] args) {NikeColthFactory nike = new NikeColthFactory();// 创建被代理类的对象ProxFactory prxoy = new ProxFactory(nike);// 创建代理类的对象prxoy.productCloth();}
}

动态代理:在程序运行时,根据被代理类及其实现的接口,动态的创建一个代理类。当调用代理类的实现的抽象方法时,就发起对被代理类同样
方法的调用。
涉及到的技术点:①提供一个实现了InvocationHandler接口实现类,并重写其invoke()方法 ②Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);
注:obj:被代理类对象 ; h:实现了InvocationHandler接口的实现类的对象
动态代理的使用

//动态代理的使用,体会反射是动态语言的关键
interface Subject {void action();
}// 被代理类
class RealSubject implements Subject {public void action() {System.out.println("我是被代理类,记得要执行我哦!么么~~");}
}class MyInvocationHandler implements InvocationHandler {Object obj;// 实现了接口的被代理类的对象的声明// ①给被代理的对象实例化②返回一个代理类的对象public Object blind(Object obj) {this.obj = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}//当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的invoke方法的调用@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//method方法的返回值时returnValObject returnVal = method.invoke(obj, args);return returnVal;}}public class TestProxy {public static void main(String[] args) {//1.被代理类的对象RealSubject real = new RealSubject();//2.创建一个实现了InvacationHandler接口的类的对象MyInvocationHandler handler = new MyInvocationHandler();//3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象。Object obj = handler.blind(real);Subject sub = (Subject)obj;//此时sub就是代理类的对象sub.action();//转到对InvacationHandler接口的实现类的invoke()方法的调用//再举一例NikeClothFactory nike = new NikeClothFactory();ClothFactory proxyCloth = (ClothFactory)handler.blind(nike);//proxyCloth即为代理类的对象proxyCloth.productCloth();}
}

动态代理与AOP

interface Human {void info();void fly();
}// 被代理类
class SuperMan implements Human {public void info() {System.out.println("我是超人!我怕谁!");}public void fly() {System.out.println("I believe I can fly!");}
}class HumanUtil {public void method1() {System.out.println("=======方法一=======");}public void method2() {System.out.println("=======方法二=======");}
}class MyInvocationHandler implements InvocationHandler {Object obj;// 被代理类对象的声明public void setObject(Object obj) {this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {HumanUtil h = new HumanUtil();h.method1();Object returnVal = method.invoke(obj, args);h.method2();return returnVal;}
}class MyProxy {// 动态的创建一个代理类的对象public static Object getProxyInstance(Object obj) {MyInvocationHandler handler = new MyInvocationHandler();handler.setObject(obj);return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);}
}public class TestAOP {public static void main(String[] args) {SuperMan man = new SuperMan();//创建一个被代理类的对象Object obj = MyProxy.getProxyInstance(man);//返回一个代理类的对象Human hu = (Human)obj;hu.info();//通过代理类的对象调用重写的抽象方法System.out.println();hu.fly();//*********NikeClothFactory nike = new NikeClothFactory();Object obj1 = MyProxy.getProxyInstance(nike);ClothFactory cloth = (ClothFactory)obj1;cloth.productCloth();}
}

效果:


反射例子

public class TestReflection {//调用指定的方法@Testpublic void test4() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;//调用非public的方法Method m1 = clazz.getDeclaredMethod("getAge");m1.setAccessible(true);int age = (Integer)m1.invoke(a);System.out.println(age);//调用public的方法Method m2 = clazz.getMethod("show", String.class);Object returnVal = m2.invoke(a,"金毛");System.out.println(returnVal);//调用static的方法Method m3 = clazz.getDeclaredMethod("info");m3.setAccessible(true);
//      m3.invoke(Animal.class);m3.invoke(null);}//调用指定属性@Testpublic void test3() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;//调用非public的属性Field f1 = clazz.getDeclaredField("name");f1.setAccessible(true);f1.set(a, "Jerry");//调用public的属性Field f2 = clazz.getField("age");f2.set(a, 9);`System.out.println(f2.get(a));System.out.println(a);//调用static的属性Field f3 = clazz.getDeclaredField("desc");System.out.println(f3.get(null));}//调用指定的构造器创建运行时类的对象@Testpublic void test2() throws Exception{Class clazz = Animal.class;Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);cons.setAccessible(true);Animal a = (Animal)cons.newInstance("Tom",10);System.out.println(a);}//获取运行时类的对象:方法一@Testpublic void test1() throws Exception{Class clazz = Class.forName("com.atguigu.review.Animal");Object obj = clazz.newInstance();Animal a = (Animal)obj;System.out.println(a);}
}

如何获取:

public class TestReflection {//关于类的加载器:ClassLoader@Testpublic void test5() throws Exception{ClassLoader loader1 = ClassLoader.getSystemClassLoader();System.out.println(loader1);ClassLoader loader2 = loader1.getParent();System.out.println(loader2);ClassLoader loader3 = loader2.getParent();System.out.println(loader3);Class clazz1 = Person.class;ClassLoader loader4 = clazz1.getClassLoader();System.out.println(loader4);String className = "java.lang.String";Class clazz2 = Class.forName(className);ClassLoader loader5 = clazz2.getClassLoader();System.out.println(loader5);//掌握如下//法一:ClassLoader loader = this.getClass().getClassLoader();InputStream is = loader.getResourceAsStream("com\\atguigu\\java\\jdbc.properties");//法二:
//      FileInputStream is = new FileInputStream(new File("jdbc1.properties"));Properties pros = new Properties();pros.load(is);String name = pros.getProperty("user");System.out.println(name);String password = pros.getProperty("password");System.out.println(password);}//如何获取Class的实例(3种)@Testpublic void test4() throws ClassNotFoundException{//1.调用运行时类本身的.class属性Class clazz1 = Person.class;System.out.println(clazz1.getName());Class clazz2 = String.class;System.out.println(clazz2.getName());//2.通过运行时类的对象获取Person p = new Person();Class clazz3 = p.getClass();System.out.println(clazz3.getName());//3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。String className = "com.atguigu.java.Person";Class clazz4 = Class.forName(className);
//      clazz4.newInstance();System.out.println(clazz4.getName());//4.(了解)通过类的加载器ClassLoader classLoader = this.getClass().getClassLoader();Class clazz5 = classLoader.loadClass(className);System.out.println(clazz5.getName());System.out.println(clazz1 == clazz3);//trueSystem.out.println(clazz1 == clazz4);//trueSystem.out.println(clazz1 == clazz5);//true}/** java.lang.Class:是反射的源头。* 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的)* 此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在在缓存区。那么这个运行时类本身就是一个Class的实例!* 1.每一个运行时类只加载一次!* 2.有了Class的实例以后,我们才可以进行如下的操作:*     1)*创建对应的运行时类的对象*     2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解、...)*     3)*调用对应的运行时类的指定的结构(属性、方法、构造器)*     4)反射的应用:动态代理*/@Testpublic void test3(){Person p = new Person();Class clazz = p.getClass();//通过运行时类的对象,调用其getClass(),返回其运行时类。System.out.println(clazz);}//有了反射,可以通过反射创建一个类的对象,并调用其中的结构@Testpublic void test2() throws Exception{Class clazz = Person.class;//      Class clazz1 = String.class;//1.创建clazz对应的运行时类Person类的对象Person p = (Person)clazz.newInstance();System.out.println(p);//2.通过反射调用运行时类的指定的属性//2.1Field f1 = clazz.getField("name");f1.set(p,"LiuDeHua");System.out.println(p);//2.2Field f2 = clazz.getDeclaredField("age");f2.setAccessible(true);f2.set(p, 20);System.out.println(p);//3.通过反射调用运行时类的指定的方法Method m1 = clazz.getMethod("show");m1.invoke(p);Method m2 = clazz.getMethod("display",String.class);m2.invoke(p,"CHN");}//在有反射以前,如何创建一个类的对象,并调用其中的方法、属性@Testpublic void test1(){Person p = new Person();
//      Person p1 = new Person();p.setAge(10);p.setName("TangWei");System.out.println(p);p.show();
//      p.display("HK");}
}

第十三章:Java_反射机制相关推荐

  1. JAVA_反射机制(照镜子)

    反射 首先反射,当你照镜子的时候你的面部的个个部位都会通过镜子反射出来,让你看道你自己.而JAVA也会像我们一样,也有一面镜子,它可以通过这面镜子,看到自己的一些信息.JAVA反射机制就是对于一段程序 ...

  2. [java学习] java_反射机制

    摘自http://baike.baidu.com/view/3454964.htm#5 反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-r ...

  3. Java反射——反射机制问题——第一章

    Java反射--反射机制问题--第一章 Java反射--Class类--第二章 Java反射--类加载--第三章 Java反射--反射获取类的结构信息--第四章 文章目录 1:一个需求引出反射 2:反 ...

  4. Effective Java之接口优先于反射机制(五十三)

    核心反射机制java.lang.reflect提供了"通过程序来访问关于已装载的类的信息"的能力,给定一个Class实例,可以获得Constructor.Method.Field实 ...

  5. 20190928 On Java8 第二十三章 注解

    第二十三章 注解 定义在 java.lang 包中的5种标准注解: @Override:表示当前的方法定义将覆盖基类的方法.如果你不小心拼写错误,或者方法签名被错误拼写的时候,编译器就会发出错误提示. ...

  6. Java反射机制应用实践

    引言 Java反射机制是一个非常强大的功能,在很多大型项目比如Spring, Mybatis都可以看见反射的身影.通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代 ...

  7. 鸟哥的Linux私房菜(服务器)- 第十三章、文件服务器之一:NFS 服务器

    第十三章.文件服务器之一:NFS 服务器 最近更新日期:2011/07/27 NFS为 Network FileSystem 的简称,它的目的就是想让不同的机器.不同的操作系统可以彼此分享个别的档案啦 ...

  8. [转]Windows Shell 编程 第十三章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7988004】...

    第十三章 Windows脚本环境 现在的许多开发人员以前都是在MS-DOS环境下编程的.几乎所有人都接触过批处理文件--一种基于文本命令的文件.这种文件使你能够在一个可执行命令中组合多个指令.批处理文 ...

  9. Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

最新文章

  1. 线性代数:第二章 矩阵及其运算
  2. 用 Java 训练深度学习模型,原来这么简单
  3. k8s 集群 Ingress Nginx传递用户真实IP问题
  4. 转:C#读取Excel文件 (2009年9月28日)
  5. mysql---表所在数据库
  6. pow(x,n) leecode
  7. matlab实现photoshop,photoshop图像滤镜——素描算法(含matlab代码)
  8. SAP ASE 多个严重漏洞的详情披露
  9. Java Bitwise Operators
  10. 重装上阵两个人合体机器人_又一部热门定档!林超贤、彭于晏领衔《紧急救援》重装定档2021年大年初一...
  11. paddlehub 使用体验-视频抠图_乘风破浪的姐姐_人美路子野 2020-08-13
  12. 【常用模块】电容触摸按键模块(原理讲解、STM32实例操作)
  13. 2019春第四次课程设计实验报告
  14. 中级计算机平面设计考试题,平面设计师(中级)技能试题答案
  15. 阿里褚霸专访-揭秘技术男开挂升级的职业路径(回帖有奖)
  16. ads1115与树莓派
  17. usb接口和计算机通信,USB接口是如何进行通信的?
  18. android主题切换框架,Prism(棱镜)——一款优秀的Android 主题动态切换框架
  19. 黑马程序员入学Java知识——精华总结
  20. 编译原理 最新版 (龙书) 简介and sources

热门文章

  1. Android -- onWindowFocusChanged
  2. JavaScript继承
  3. 演示FileInputStream案例演示
  4. DNS视图及日志系统
  5. (1)memcached应用
  6. 简述MVC思想与PHP如何实现MVC
  7. 新书《活用UML-需求分析高手》详细大纲(持续更新中)
  8. Programming WCF Services翻译笔记(五)
  9. OSChina_IOS版客户端笔记(四)_程序数据、缓存的管理
  10. 定位低效SQL与不同的Extra类型(转载)