Java多态与反射


多态通过分离做什么和怎么做,从另一个角度将接口与实现分离开来;通过多态来消除类型之间的耦合关系,在Java中,多态也叫动态绑定,后期绑定或运行时绑定,那么什么是方法绑定?

方法调用绑定:

将一个方法与调用同一个方法的主体关联起来被称为绑定;若在程序执行前进行绑定(由编译器和连接程序实现),叫做前期绑定;还有一种叫后期绑定,就是在运行时根据对象的类型进行绑定,也叫动态绑定或运行时绑定,也就是说,编译器不知道对象的类型,但是方法调用机制能找到正确的方法体;在Java中除了static方法和final方法之外,所有的其他方法都是后期绑定;

因此,Java中所有的方法都是通过动态绑定来实现多态的,但如果直接访问某个域,则这个访问就会在编译其进行解析;一般我们都通过将子类向上转型为父类来实现多态,父类可以是抽象类,只要子类实现到父类的所有抽象方法,就可以将子类转型为抽象的父类;Java里的抽象类本身是不能被实例化,但可以将子类的引用向上转型为抽象的父类。
如:

abstract class Jack{public abstract void doSomething();}
class Product extends Jack{@Overridepublic void doSomething() {System.out.println("Product");}}public static void main(String[] args) {//声明一个抽象类Jack的变量,并指向其子类的实例化对象,合法的,Java的多态性会保证在运行时可以得到其正确的类型;Jack jack=new Product();//Jack jack=new Jack();//非法,不能实例化抽象类对象jack.doSomething();}

Java反射

Java反射机制是指在运行状态时,可以知道任意一个类的的所有属性和方法,对任意一个对象都可以调用它的任意一个方法;通过反射,可以在运行时实例化对象

Java反射提供的功能包括:

  • 在运行时判断一个对象所属的类;
  • 运行时构造任意一个类的对象;
  • 运行时判断任意一个类的成员变量与方法;
  • 运行时调用任意一个对象的方法;
  • 生成动态代理;

我们想得到一个类的所有信息,第一步就是要得到类的Class对象,如果知道了一个对象或类的名字,就可以通过简单的:
Class<?> clz=对象.getClass();
Class<?> clz=类的名字.class
得到,但如果在编译期得不到具体类型,则可以通过Class.forName()来得到,但这个方法生成的结果在编译时是不可知的,所有的方法特征签名都是在运行时提取出来的。这是由Java的反射机制来提供足够的支持。在得到这个类的Class对象后,我们就可以反射来构造对象,进而得到这个类的所有的信息。

 public static Class<?> forName(String className)throws ClassNotFoundException {Class<?> caller = Reflection.getCallerClass();return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}

Java里的Class类与java.lang.reflect类库一起对反射进行支持,该类库包含了Field,Method,Constructor类(每个类都实现了Member接口),这些类型的对象是在JVM在运行时创建的,用以表示未知类里对应的成员。这样我们就可以使用Constructor创建新的对象,用get(),set()方法修改与Field对象关联的字段,用invoke()方法调用与Method对象关联的方法。(摘自《Java编程思想》第四版)

下面简要介绍利用反射实现的动态代理;

动态代理

步骤:

  • 新建委托类,实现动态代理要求委托类必须实现某个接口;
  • 新建中间类,用来连接代理类和委托类,这个中间必须实现InvocationHandler接口,这个接口只有一个invoke()方法;
  • 通过Proxy类新建代理类对象;

举例:

interface Operate{void method1();void method2();void method3();}/*** 委托类* @author wood**/class Entrust implements Operate{@Overridepublic void method1() {// TODO Auto-generated method stubSystem.out.println("*method1");}@Overridepublic void method2() {// TODO Auto-generated method stubSystem.out.println("*method2");}@Overridepublic void method3() {// TODO Auto-generated method stubSystem.out.println("*method3");}}/*** 连接委托类与代理类的中间类;* @author wood**/class DynamecProxyHandler implements InvocationHandler{private Object proxied;//委托类对象public DynamecProxyHandler(){}public DynamecProxyHandler(Object object){this.proxied=object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] arg2)throws Throwable {// TODO Auto-generated method stubObject object=method.invoke(proxied, arg2);System.out.println(method.getName());return object;}}//***********************DynamecProxyHandler dymaProxy=new DynamecProxyHandler(new Entrust());//通过Proxy类的静态函数生成代理对象;Operate operate=(Operate)Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[]{Operate.class}, dymaProxy);operate.method1();operate.method2();operate.method3();

我们通过Procy.newProcyInstance函数新建了一个代理对象,实际的代理类就是在这时候动态生成了,我们调用该代理对象的函数就会调用到中间类的invoke函数,而invoke函数实现调用委托类的对应函数;

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader是类加载器;
interfaces是委托类的接口,生成代理需要实现这个接口;

实际上Java的动态代理就是两层的静态代理:开发者提供一个委托类A,程序动态生成了一个代理类B,开发者还需要提供一个实现了InvocationHandler的接口C,用类C来连接委托类A和委托类B,类C是代理类B的委托类,是类A的代理类;用户直接调用代理类B,B将调用转发给委托类C,C再将调用转发给委托类A;

参考:
《Java编程思想》第四版
公共技术点之 Java 动态代理

转载于:https://www.cnblogs.com/WoodJim/p/4722107.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java webservice用户验证_使用java webservice的.net4.0 web app需要Usernametoken身份验证

我是使用.net 4.0 VS2010的新手。我需要使用java web服务并发送usernametoken自定义身份验证来访问服务&#xff0c;这是我很容易在VS2005中使用WSE2.0&#xff0c;那么在net 4.0中替换它是什么&#xff1f;我的客户端是.net 4.0 Asp.net Web应用程序(网站)&#xff0c;服务是j…

python随机数模块_python 随机数模块 -- random

一、概述这个模块实现的伪随机数生成器。对于整数&#xff0c;从区间选取。对于序列&#xff0c;随机元素。在实线的&#xff0c;有功能来计算均匀分布&#xff0c;正态分布(高斯) &#xff0c;对数正态分布&#xff0c;负指数&#xff0c;γ和β分布。对于生成的角度分布&…

织梦dedecms5.7二级域名文章图片不显示修改方法.相对路径改为绝对路径的方法...

dedecms升级到5.7SP1后&#xff0c;开启二级域名&#xff0c;你会发现&#xff0c;在二级域名下的文章&#xff0c;上传的图片地址都是&#xff1a;二级域名图片地址&#xff0c;这是相对路径。但是你的图片是默认上传在uploads里面的。应该使用绝对路径。这就出现图片路径错误…

java注册中心nacos_spring-cloud整合nacos做注册中心

前面讲了spring-cloud整合nacos做配置中心&#xff0c;这节讲一下nacos做注册中心至于注册中心是什么&#xff0c;我就不讲了&#xff0c;不了解的可以去问度娘下面我就直接开始了&#xff0c;也是比较简单的&#xff1a;1.引入依赖1.8Greenwich.SR12.1.0.RELEASEorg.springfra…

python批量转换图片格式_python批量将图片转换为JPEG格式

标签&#xff1a;# -*- coding:utf-8 -*-import osfrom PIL import Imagedef resize(path):filelist os.listdir(path)for i in filelist:img Image.open(path i)outfile os.path.splitext(i)[0] .jpegif img ! outfile:img.save("C:/Users/Administrator/Desktop/最…

判断 JS 中对象的类型

1.typeof 形如 var x "xx"; typeof x string typeof(x) 返回类型有&#xff1a;undefined “string” number boolean function object 缺点&#xff1a;对于object类型不能细分是什么类型 优点&#xff1a;对空null的判断 undefined的应用 2.instanceof 形如 var …

java中接口回调_Java中的接口回调实例

定义&#xff1a;/*** author Administrator* project&#xff1a; TestOne* package&#xff1a; PACKAGE_NAME* date&#xff1a; 2018/11/30 0030 15:42* brief: 郭宝**/public class Person {/*** 自定义一个接口**/public interface OnNameChangeListener{//接口中的抽象函…

python经纬度转换xy坐标公式_python 经纬度和平面坐标相互转换利用米勒坐标系

xy_coordinate [] # 转换后的XY坐标集def millerToXY (lon, lat):"""经纬度转换为平面坐标系中的x,y 利用米勒坐标系:param lon: 经度:param lat: 维度:return:"""L 6381372*math.pi*2W LH L/2mill 2.3x lon*math.pi/180y lat*math.pi/1…

Android基于mAppWidget实现手绘地图(二)--概要

离线地图是一张被切成类似瓷砖般格子图像组成&#xff0c;这些被切开的格子组织成多个缩放级别。缩放级别是从0开始。0这个缩放级别&#xff0c;地图图像的尺寸为1*1像素。在每下一个缩放级别&#xff0c;图像尺寸则会两倍递增。 每个地图都是有层和地图对象的。 层是一个抽象的…

java实体字节属性定义_Java字节码方法表与属性表详解

而这些字节其实对应的信息是它&#xff1a;所以问题就来了&#xff0c;aload_0不是助记符信息么&#xff0c;怎么就能够跟字节码文件中的字节对应上呢&#xff1f;所谓助记符其实也就是帮忙我们去记忆的符合&#xff0c;在底层其实也是对应的一个个十六进制的数字的&#xff0c…

允许使用抽象类类型 isearchboxinfo 的对象_此对象非彼对象(面向对象)3

java13面向对象深入3大纲这里没有写面向对象-封装性理解封装( encapsulation)怎么去理解&#xff0c;一台电脑利用一个外壳包裹&#xff0c;保护了里面的电器元件&#xff0c;提供了少量的按键与其对接使用。我要看电视&#xff0c;只需要按一下开关和换台就可以了。有必要了解…

python turtle库输出文字_python turtle库学习笔记

#绘制时钟#codingutf-8importturtle as ttfrom datetime import *#当前日期属于一周的第几天defWeek(t):week ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]returnweek[t.w…

后勤报修项目心得

耗时两天左右&#xff0c;完成了预期任务&#xff0c;来做个总结1.简单说下感受2.说说整个经历3.温习下自己在实战项目操作过程中出现的问题 1.因为之前有过一个礼拜左右时间上手预热项目&#xff0c;果然这样学就是上手快&#xff0c;比起在学校里的课&#xff0c;效率提升了很…

hbase java admin_java连接hbase(一):Admin功能接口表管理

本文hbase版本基于hbase-1.0.0-cdh5.6.1。Admin接口主要操作表创建&#xff0c;删除&#xff0c;列族的增删&#xff0c;表的清空&#xff0c;region的增删&#xff0c;合并操作。import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.HBaseConfigurat…

复制url直接能跳过验证_python 爬虫如何突破登录验证

我用 python 做爬虫爬过不少数据&#xff0c;比如在 google play 爬应用信息&#xff1b;在 instragram, 500px 爬图片&#xff1b;当然爬虫的作用不止于此&#xff0c;比如定时去某个网站签到&#xff0c;妈妈再也不用担心我忘记签到了这些网站支持游客访问&#xff0c;但要访…

[2-sat]HDOJ3062 Party

中文题 题意略 学2-sat啦啦啦 2-sat就是 矛盾的 ($x、x’$不能同时取) m对人 相互也有限制条件 取出其中n个人 也有可能是把一件东西分成 取/不取 相矛盾的两种情况 (那就要拆点啦~) 取其中n件 做法是 暴力 和 强连通 两种 重点在于建图&#xff1a; 对于x&#xff0c;记 取…

node作为java中间间_node作为中间服务层如何发送请求(发送请求的实现方法详解)...

GET请求&#xff1a;var http require(http);var qs require(querystring);var data {a: 123,time: new Date().getTime()};//这是需要提交的数据var content qs.stringify(data);var options {hostname: 127.0.0.1,port: 10086,path: /pay/pay_callback? content,metho…

python目标识别代码_利用ImageAI库只需几行python代码超简实现目标检测

什么是目标检测目标检测关注图像中特定的物体目标&#xff0c;需要同时解决解决定位(localization) 识别(Recognition)。相比分类&#xff0c;检测给出的是对图片前景和背景的理解&#xff0c;我们需要从背景中分离出感兴趣的目标&#xff0c;并确定这一目标的描述(类别和位置…

Winodws live writer

发布一篇试试。 转载于:https://www.cnblogs.com/DotNetCSharp/p/4742956.html

java里面value_「Java基础知识」Java中包含哪些运算符

原标题&#xff1a;「Java基础知识」Java中包含哪些运算符在Java中包含的运算符有&#xff1a;算数运算符&#xff0c;逻辑运算符&#xff0c;关系运算符等。算数运算符也就是我们平时的加减乘除余等操作&#xff1a;在Java中都是将右边的值赋值给左边&#xff0c;所以一般格式…