跟着刚哥梳理java知识点——反射和代理(十七)
反射机制是什么?
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有的属性和方法
;对于任意一个对象,都能够调用他的一个方法和属性,这种动态获取的信息以及
动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么?
 反射机制主要提供以下功能
  √ 在运行时判断任意一个对象所属的类
  √ 在运行时构造任意一个类的对象
  √ 在运行时判断任意一个类所具有的的属性和方法
  √ 在运行时调用一个对象的方法
  √ 生成动态代理
通过一个对象获得完整的包名和类名
package com.hzg;
public class TestReflect {
public static void main(String[] args) throws Exception {
TestReflect testReflect = new TestReflect();
System.out.println(testReflect.getClass().getName());
// 结果 com.hzg.TestReflect
}
}
通过一个对象获得完整的属性、方法
Class clazz = Person.class();
//1、创建clazz对象的运行时类Person对象
Person p = (Person)clazz.getInstance();
//2、通过反射调用运行时的指定属性
Filed f1 = clazz.getField("name");
f1.set(p,"LiudeHua");
//3、通过反射调用运行时的指定的方法
Method m1 = clazz.getMethod("show",String.class);
m1.invoke(p,"CHN");
注意:Class可不是关键字class,Class是类名字,class是个关键字标识是类
获取class的实例(3种方式)
  ①调用运行时类本身的.class属性
    Class clazz = Person.class;
  ②通过运行时类的对象获取
    Person p = new Person();
    Class clazz = p.getClass();
  ③通过class的静态方法获取
    Class clazz = Class.forName("com.hzg.TestReflect");
package com.hzg;
public class TestReflect {
public static void main(String[] args) throws Exception {
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
// ① 静态方法(一般采用这种形式)
class1 = Class.forName("com.hzg.TestReflect");
// ② 运行时类的对象获取
class2 = new TestReflect().getClass();
// ③ 类本身.class属性
class3 = TestReflect.class;
System.out.println("类名称 " + class1.getName());
System.out.println("类名称 " + class2.getName());
System.out.println("类名称 " + class3.getName());
}
}
获取一个对象的父类与实现的接口
package com.hzg;
import java.io.Serializable;
public class TestReflect implements Serializable {
private static final long serialVersionUID = -2862585049955236662L;
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.hzg.TestReflect");
// 取得父类
Class<?> parentClass = clazz.getSuperclass();
System.out.println("clazz的父类为:" + parentClass.getName());
// clazz的父类为: java.lang.Object
// 获取所有的接口
Class<?> intes[] = clazz.getInterfaces();
System.out.println("clazz实现的接口有:");
for (int i = 0; i < intes.length; i++) {
System.out.println((i + 1) + ":" + intes[i].getName());
}
}
}
有了class实例以后,可以做什么呢?
  ① 可以创建对应运行时类的对象
  ② 获取对应运行是类的完整的类的结构:属性、方法、构造器、包、泛型、注解、异常、内部类。
    如 Method[] m1 = clazz.getMethods():获取类和父类的所有public方法
         Method[] m1 = clazz.getDeclaredMethods():所有修饰符方法
         但是不含父类,只有这个类的中所有修饰符方法
  ③ 调用运行是类中指定的结构(属性、方法、构造器)
    √ 获取指定属性:Field name = clazz.getField("name");
    √ 设置指定public属性:name.set(p,"hzg"); 
    √ 设置指定private属性:
      Field name = clazz.geDeclaredtField("name");
      name.setAccessible(true);
      name.set(p,"hzg");
    √ 获取指定的方法:Method m1 = clazz.getMethod("show");
    √ 调用指定的方法:
      Object obj = m1.invoke(p); 返回类型就是方法的返回类型
    √ 调用静态方法:m1.invoke(Person.class);
    √ 调用带参数的指定方法:
      Method m1 = clazz.getDeclatedMethod("show1",String.class);
      Object obj = m1.invoke(p,"hzg");
    √ 调用构造器:Constructor con = clazz.getDeclaredConstructor();
    √ 调用带参数构造器,和带参数方法一致
Java反射的应用---代理
1、静态代理(基于接口的多态性实现的静态代理)
 interface ClothFactory{
   void productCloth();
 }
 //被代理类
 class NikeClothFactory implements ClothFactory{
   @Override
   public void productCloth(){
     sysytem.out.printLn("NIKE工厂生产一批衣服");
   }
 }
 //代理类
 class ProxyFactory implements ClothFactory{
   ClothFactory cf;
   public ProxyFactory(ClothFactory cf){
     this.cf = cf;
   }
   @Override
   public void productCloth(){
     sysytem.out.printLn("代理类开始执行,收代理费1000");
     cf.productCloth();
   }
 }
 public class Test{
   public static void main(String[] args){
     //① 创建一个被代理对象
     NikeClothFactory nike = new NikeClothFactory ();
     //② 创建一个代理类对象
     ProxyFactory proxy = new ProxyFactory(nike);
     //③ 调用代理类对象的方法
     proxy.productCloth();
   }
 }
静态代理总结:
① 代理类和被代理类都实现同一个接口
② 代理类和被代理类都实现接口中的方法
缺点:每个被代理类都需要一个代理类来完成,这样程序需要过多的代理,思考:是否能有一个万能的代理类完成全部的代理功能?
2、动态代理(基于反射实现的动态代理)
 interface ClothFactory{
   void productCloth();
 }
 //被代理类
 class NikeClothFactory inplements ClothFactory{
   @Override
   public void productCloth(){
     sysytem.out.printLn("NIKE工厂生产一批衣服");
   }
 }
 //①必须实现InvocationHandler接口
 class MyInvocationHandler implements InvocationHandler{
   //② 声明接口的代理类
   Object obj;
   //③ 创建一个方法实例化代理类
   public Object bind(Object obj){
     this.obj = obj;
     return Proxy.newProxyInstance(
     obj.getClass().geyClassLoder(),
     obj.getClass().getInterfaces(),this);
   }
   //④ 实现接口InvacationHandler的方法
   // 此方法实现:当调用代理类的对象方法的时候,都会转换到它上调用
   @Override
   public Object invoke(Object proxy,Method method,Object[] args){
     Object returnVal = method.invoke(obj,args);
     return returnVal();
   }
 }
 //调用实现一下
 public class Test{
   public static void main(String[] args){
     //① 老规矩:创建一个被代理对象
     NikeClothFactory nike = new NikeClothFactory ();
     //②老规矩:创建一个代理类对象
     MyInvocationHandler hander = new MyinvocationHanlder();
     ClothFactory proxyCloth = (ClothFactory)hander.bind(nike);
     //③ 老规矩:调用代理类对象的方法
     proxyCloth .productCloth();
   }
 }
跟着刚哥梳理java知识点——反射和代理(十七)的更多相关文章
- 跟着刚哥梳理java知识点——面向对象(八)
		
面向对象的核心概念:类和对象. 类:对一类事物描述,是抽象的.概念上的定义. 对象:实际存在的该类事物的每个个体,因而也成为实例(Instance). Java类及类的成员:属性(成员变量Field) ...
 - 跟着刚哥梳理java知识点——多线程(十六)
		
创建多线程第一种方式:① 继承:继承Thread.② 重写:重写Thread类的run()方法③ 创建:创建一个子类的对象④ 调用:调用线程的start()方法,启动此线程,调用run()方法 cla ...
 - 跟着刚哥梳理java知识点——深入理解String类(九)
		
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
 - 跟着刚哥梳理java知识点——变量之间的类型转换(四)
		
变量之间的类型转换主要包括自动类型转换和强制类型转换. 1.自动类型转换:当容量小的数据类型与容量大的数据类型做运算时,容量小的会自动的转换成容量大的类型. [知识点]: a)char,byte,sh ...
 - 跟着刚哥梳理java知识点——注释(二)
		
1.单行注释 // //这是main方法,程序的入口 public static void main(String[] args) { //输出语句 System.out.println(" ...
 - 跟着刚哥梳理java知识点——HelloWorld和常见问题(一)
		
1.按照国际惯例,写一段输出HelloWorld的java语句: public class HelloWorld { //这是main方法,程序的主入口 public static void main ...
 - 跟着刚哥梳理java知识点——IO(十五)
		
凡是与输入.输出相关的类.接口都定义在java.io包下 java.io.File类 1.File是一个类,可以有构造器创建其对象.此对象对应着一个文件或者一个目录. 2.File中的类,仅涉及到如何 ...
 - 跟着刚哥梳理java知识点——枚举和注解(十四)
		
enum Season{ SPRING("spring","春暖花开"), SUMMER("summer","夏日炎炎" ...
 - 跟着刚哥梳理java知识点——泛型(十三)
		
一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: public class GenericTest { public static void main(String[] a ...
 
随机推荐
- SpringBoot之旅 --  SpringBoot 项目健康检查与监控
			
前言 You build it,You run it, 当我们编写的项目上线后,为了能第一时间知晓该项目是否出现问题,常常对项目进行健康检查及一些指标进行监控. Spring Boot-Actuato ...
 - Https握手协议以及证书认证
			
1. 什么是https Https = http + 加密 + 认证 https是对http的安全强化,在http的基础上引入了加密和认证过程.通过加密和认证构建一条安全的传输通道.所以https可以 ...
 - Python Number(数字)
			
---Number类型的细节,其包含的基本数字类型 ---Number基本数字类型之间的数值转换 ---Number上面的数学函数,有些可以直接调用,有些需要导入库 参见http://www.runo ...
 - 分享几个不错的Android开源音视频播放器
			
整理了一下Github上几个开源的音视频播放器项目,有兴趣的同学可以clone代码去研究学习. UniversalMusicPlayer https://github.com/googlesamp ...
 - WebX框架学习笔记之二----框架搭建及请求的发起和处理
			
框架搭建 执行环境:windows.maven 执行步骤: 1.新建一个目录,例如:D:\workspace.注意在盘符目录下是无法执行成功的. 2.执行如下命令: mvn archetype:gen ...
 - windos环境apache+mysql+php+Discuz的安装配置
			
首先是相关软件的下载:PHP.Apache和Mysql软件以及VC库.相关软件可到我的百度网盘下载,百度网盘:http://pan.baidu.com/s/1o6DYcMu 相关软件的直接下载地址: ...
 - MVC学习笔记3 - JsRender
			
许多发展平台减少代码和简化维护,使用模板和 HTML5 和 JavaScript 也不例外. JsRender 是一个 JavaScript 库使您可以一次定义一个样板文件结构,并使用它来动态地生成 ...
 - for语句输出三角形
			
public class yuju { public static void main(String[] args) { ; i<; i++) { ; j<=i;j++) { System ...
 - React-Native 之 项目实战(三)
			
前言 本文有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关. 如文中内容对 ...
 - Java设计模式GOF之单例模式
			
一.单例模式(Singleton) 1.单例模式应用场景: ①Servlet ②任务管理器 ③链接池 ④Spring中每个 bean 默认是单例 ⑤网站计数器 2.单例要求 ①构造器私有 ②私有的静态 ...