Javaインスタンス化インタフェースまたは抽象クラス
8300 ワード
1.インスタンス化インタフェース:
ある日、クラスのメソッドを反射で呼び出したいのですが、メソッドパラメータにインタフェースがあることがわかりました.インタフェースがインスタンス化できないことを知っています.どうすればいいですか.
例:
I/TestLib: myTest start executing I/MainActivity: doFail I/MainActivity: doSucc
ある日、クラスのメソッドを反射で呼び出したいのですが、メソッドパラメータにインタフェースがあることがわかりました.インタフェースがインスタンス化できないことを知っています.どうすればいいですか.
例:
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.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?) {
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!
成功!
总结,调用含抽象类或接口参数的方法,需要传入一个对象,这时候就需要实例化类或接口!
転載先:https://www.cnblogs.com/lzh-Linux/p/9149262.html