Java 实例化接口或抽象类
1、 实例化接口:
某一天,我们想通过反射调用一个类的方法,但发现方法参数中有一个接口,我们都知道接口不能被实例化,这该怎么办呢?
举例:
public class TestLib {
public static final String TAG = "TestLib";
void myTest(MyInterface myInterface) {
Log.i(TAG, "myTest start executing ");
myInterface.doFail();
myInterface.doSucc();
}
}
我们想通过反射调用TestLib.myTest(...)方法,
public interface MyInterface {
void doFail();
void doSucc();
}
但参数是个接口,仔细一想,我们可以通过动态代理实现接口啊!
实现:
// Step one:
val TestLibClass = Class.forName("demo.apt.aptyyb.TestLib")
val TestLibObject = TestLibClass.newInstance()
// Step two:
val myTestMethod = TestLibClass.getDeclaredMethod("myTest",
Class.forName("demo.apt.aptyyb.MyInterface"))
//Step three:
val interfaceObject = Proxy.newProxyInstance(classLoader,
arrayOf<Class<*>>(Class.forName("demo.apt.aptyyb.MyInterface")), MyInvoke())
//Step four:
myTestMethod.invoke(TestLibObject, interfaceObject)
再看MyInvoke的定义:
inner class MyInvoke : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?) {
if (method?.name.equals("doFail")){
Log.i(TAG,"doFail")
}else if (method?.name.equals("doSucc")){
Log.i(TAG,"doSucc")
}
}
最后Run,看结果:
I/TestLib: myTest start executing
I/MainActivity: doFail
I/MainActivity: doSucc
2、实例抽象类
上面通过动态代理在内存中实例化了接口,那么抽象类该如何处理呢?
2018年的某天,风和日丽,像往常一样开始码代码,生命不止,码码不息:
现在在TestLib中又多了一个方法,
void abstractTest(MyAbstract myAbstract){
Log.i(TAG, "abstractTest start executing ");
myAbstract.doFail();
myAbstract.doSucc();
}
what is the “MyAbstract”???
public abstract class MyAbstract {
static {
Log.i("Lib", "MyAbstract Main is load");
}
private static final String TAG = "MyAbstract";
public void doFail() {
Log.i(TAG, "MyAbstract Main doFail");
}
public abstract void doSucc();
}
原来是一个抽象类啊!那么问题来了,如何通过反射调用含抽象类的方法呢?
使用DexClassLoader!插件化技术来实现!
新建一个Lib工程,放置两个类,
public abstract class MyAbstract {
static {
Log.i("Lib","MyAbstract Plugin is load");
}
public void doFail() {
}
public abstract void doSucc();
}
public class LibPlugin extends MyAbstract {
private static final String TAG = "LibPlugin";
public LibPlugin() {
Log.i(TAG,"LibPlugin Plugin constructor is executing" +
"!");
}
@Override
public void doFail() {
Log.i(TAG,"LibPlugin Plugin doFail" +
"!");
}
@Override
public void doSucc() {
Log.i(TAG,"LibPlugin Plugin doSucc" +
"!");
}
}
生成apk文件,push到sd卡中, 然后使用DexClassLoader加载LibPlugin 这个类:
// 第一步加载LibPlugin类:
val dexPath=Environment.getExternalStorageDirectory().absolutePath+"/dexlib-debug.apk"
val dexLoader=DexClassLoader(dexPath,getDir("app",0).absolutePath,null,classLoader)
val abstractClass=dexLoader.loadClass("demo.apt.dexlib.LibPlugin")
第二步找到要调用的方法:
val TestLibClass = Class.forName("demo.apt.aptyyb.TestLib")
val TestLibObject = TestLibClass.newInstance()
val myAbstractMethod = TestLibClass.getDeclaredMethod("abstractTest",
Class.forName("demo.apt.aptyyb.MyAbstract"))
第三步直接Invoke:
myAbstractMethod.invoke(TestLibObject,abstractClass.newInstance())
好了,到此就完成了我们得反射调用含抽象类参数的方法。
看下输入的结果:
I/Lib: MyAbstract Main is load
I/LibPlugin: LibPlugin Plugin constructor is executing!
I/TestLib: abstractTest start executing
I/LibPlugin: LibPlugin Plugin doFail!
I/LibPlugin: LibPlugin Plugin doSucc!
成功!
总结,调用含抽象类或接口参数的方法,需要传入一个对象,这时候就需要实例化类或接口!
Java 实例化接口或抽象类的更多相关文章
- Java中接口和抽象类的比較
Java中接口和抽象类的比較-2013年5月写的读书笔记摘要 1. 概述 接口(Interface)和抽象类(abstract class)是 Java 语言中支持抽象类的两种机制,是Java程序设计 ...
- 慢慢人生路,学点Jakarta基础-深入剖析Java的接口和抽象类
在java面向对象编程的,抽象类和接口始终存在有疑问的地方,因为两者太多相似有太多不同,在刚开始学习的时候经常弄的不对,使用情景搞混,今天来总结之前学习Java中接口和抽象类的问题. 抽象类 了解:只 ...
- 深入理解Java的接口和抽象类(转)
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- 深入理解Java的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- [转载]深入理解JAVA的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- 深入理解Java的接口和抽象类 _摘抄
http://www.cnblogs.com/dolphin0520/p/3811437.html 原文 深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可 ...
- Java进阶(三十六)深入理解Java的接口和抽象类
Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...
- 【转】深入理解Java的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- 33、深入理解Java的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
随机推荐
- HDU - 6736 F - Forest Program
题意 给你n个点m条边,并且保证整个图是仙人掌. 仙人掌:每条边仅属于1条或者0条回路 且无重边和自环 让你删掉一些边使其变成一棵树(拥有点数-1条边) 注意一个点也是森林 图可能是不联通的 思路 考 ...
- CPU 底层运算之乘法运算
CPU 运算加减法运算 假设计算 3+3 原码是0011 * 0011(以4位存贮单元,因为是原码,最高位不代表符号位) 1. 首先 判断 两个加数是否有 负数(减法) 如果有 负数 先将负数转 ...
- OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...
- 创建Sqlite数据库(一)
对这方面的掌握不牢,慢慢深入吧,先执行一个sqlite语句,只会简单的.输出"创建"证明创建成功 public class MainActivity extends AppComp ...
- 一些常见JAVA问题
原文:https://blog.csdn.net/weiyongxuan/article/details/45920765 一.Java的异常的基类是java.lang.Throwable 二.守护线 ...
- B. Two Fairs 解析(思維、DFS、組合)
Codeforce 1276 B. Two Fairs 解析(思維.DFS.組合) 今天我們來看看CF1276B 題目連結 題目 給一個連通圖,並給兩個點(\(a,b\)),求有多少點對使得:任一路徑 ...
- robotframework执行自动化不能转换为h5页面的问题解决
电脑换成win10后,搭建了robotframework环境,执行自动化发现页面不支持h5页面了.请教了大佬,解决办法如下: 1.切换到DOS环境下,执行pip list命令,查看selenium2l ...
- Zabbix批量添加Hosts
添加脚本 addhost.py #coding:utf-8 import json import urllib2 from urllib2 import URLError import sys imp ...
- 物流一站式单号查询之快递鸟API接口(附Demo源码)
连载篇提前看 物流一站式单号查询之快递鸟API接口 物流一站式查询之TrackingMore篇 物流一站式查询之顺丰接口篇 物流一站式查询之快递100 前情提要 前三篇中,我们已经从注册.申请接口.调 ...
- java查询elasticsearch聚合
java查es多分组聚合: SearchRequestBuilder requestBuilderOfLastMonth = transportClient.prepareSearch(TYPE_NA ...