Java反射调用一篇就够了

本文详细介绍了Java反射的使用,包括类和方法的调用、带参数构造函数的创建以及实现接口的方法。通过示例代码展示了如何动态调用类方法、创建对象、模拟接口实现,以及在构建者模式中使用反射。此外,还提及了在实际开发中如何通过反射实现广告SDK的初始化配置。
摘要由CSDN通过智能技术生成

Java反射调基础和进阶使用方法

一、类和方法调用

//        AAAManager.getInstance().initWith(context, appId);
        try {
            Class<?> class1 = Class.forName("com.XXX.AAAManager");
            Method method = class1.getMethod("getInstance");
            Method method2 = class1.getMethod("initWith", new Class[]{Context.class,String.class});
            //调用方法(第一个参数为对象,第二个参数到最后一个参数为方法属性值)
//            method.invoke(class1); // 反射调用静态方法

// 			  class1.newInstance()反射无参的构造方法
//            method.invoke(class1.newInstance(), context, appId);
            method2.invoke(method.invoke(class1), context, appId);


        } catch (Exception e) {
            Log.d("error", e.toString());
            e.printStackTrace();
        }
二、带参数的构造函数的类
        Class<?> clazz=Class.forName("com.sanmao10.Person");
        
        Constructor con = clazz.getDeclaredConstructor(String.class,int.class);//获取有参构造
         Object obj = con.newInstance(str1, age);

三、使用反射方式去实现一个接口
  • 强制转换赋值给反射出来的实例
1、非反射的写法
// 非反射的写法
//  SplashAD splashAD = new SplashAD(activity, posId, new SplashADListener() {
//            @Override
//            public void onADDismissed() {
//                activity.runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                    }
//                });
//            }
//
//            @Override
//            public void onNoAD(final AdError adError) {
//                activity.runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        errorListener.onerror();
//                    }
//                });
//            }
// }
// splashAD.fetchAndShowIn(container);

2、反射
try {
            Class<?> splashADClass = Class.forName("com.qq.e.ads.splash.SplashAD");
            Class<?> mSplashADListener = Class.forName("com.qq.e.ads.splash.SplashADListener");

            Constructor con = splashADClass.getDeclaredConstructor(Context.class, String.class, mSplashADListener);

            Object listener = Proxy.newProxyInstance(mSplashADListener.getClassLoader(),
                    new Class[] { mSplashADListener }, new SplashADListenerImpl(activity, posId, aaaListener, errorListener));

            Object obj = con.newInstance(activity, posId, listener);

            Method method2 = splashADClass.getMethod("fetchAndShowIn", new Class[]{ViewGroup.class});

            method2.invoke(obj, container);
        } catch (Exception e) {
            e.printStackTrace();
        }


private class SplashADListenerImpl implements InvocationHandler {

        private Activity activity;
        private String posId;
        private AAAListener Listener;
        private SDKErrorListener errorListener;

        public SplashADListenerImpl(final Activity activity, String posId, final AAAListener aaaListener, final SDKErrorListener errorListener) {
            this.activity = activity;
            this.posId = posId;
            this.aaaListener = aaaListener;
            this.errorListener = errorListener;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            try {

                Log.e("TAG", "invoke, method: " + method.getName());

                if("onADDismissed".equals(method.getName())) {
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            osetListener.onClose();
                        }
                    });
                } else if("onNoAD".equals(method.getName())) {
				// 强制转换赋值给反射出来的实例
                    // 未用反射正常的写法
//                    AdError mAdError = (AdError) args[0];

                    // 因为反射需要
                    Class<?> AdErrorClass = Class.forName("com.qq.e.comm.util.AdError");
                    Object mAdErrorObj = AdErrorClass.cast(args[0]);

                    Method method1 = AdErrorClass.getMethod("getErrorCode");
                    Method method2 = AdErrorClass.getMethod("getErrorMsg");

                    final String codeErr = (String) method1.invoke(mAdErrorObj);
                    final String codeErrMsg = (String) method2.invoke(mAdErrorObj);

                    Log.e("TAG", "invoke, args, path: " + method1.invoke(mAdErrorObj) + method2.invoke(mAdErrorObj));
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            errorListener.onerror();
                        }
                    });
                } 
            } catch (Exception e) {
                Log.e("Exception", e.toString());
            }
            return proxy;
        }
    }
构建者(Builder)模式
1、不是反射
        TTAdSdk.init(context,
                new TTAdConfig.Builder()
                        .appId(appId)
                        .useTextureView(false) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
                        .appName(context.getApplicationInfo().name)
                        .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
                        .allowShowNotify(true) //是否允许sdk展示通知栏提示
                        .allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
                        .debug(false) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
                        .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_4G) //允许直接下载的网络状态集合
                        .supportMultiProcess(true) //是否支持多进程,true支持
                        //.httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
                        .needClearTaskReset()
                        .build());
2、反射实现
try {  // TTAdConfig.Builder
            Class<?> TTAdSdkClass = Class.forName("com.bytedance.sdk.openadsdk.TTAdSdk");
            Class<?> TTAdConfigClass = Class.forName("com.bytedance.sdk.openadsdk.TTAdConfig");
            Class<?> TTAdConfigBuilderClass = Class.forName("com.bytedance.sdk.openadsdk.TTAdConfig$Builder");

            Method method0 = TTAdSdkClass.getMethod("init", new Class[]{Context.class, TTAdConfigClass});

//            Method method = TTAdConfigClass.getMethod("Builder"); // 错误的

            Method method2 = TTAdConfigBuilderClass.getMethod("appId", new Class[]{String.class});
            Method method3 = TTAdConfigBuilderClass.getMethod("useTextureView", new Class[]{boolean.class});

            Method method4 = TTAdConfigBuilderClass.getMethod("appName", new Class[]{String.class});
            Method method5 = TTAdConfigBuilderClass.getMethod("allowShowNotify", new Class[]{boolean.class});

            Method method6 = TTAdConfigBuilderClass.getMethod("build");

            //调用方法(第一个参数为对象,第二个参数到最后一个参数为方法属性值)
//            method.invoke(class1); // 反射调用静态方法
//            method.invoke(class1.newInstance(), context, appId);

//            method2.invoke(TTAdConfigBuilderClass.newInstance(), appId);

            Object configObj = method6.invoke(method5.invoke(method4.invoke(method3.invoke(method2.invoke(TTAdConfigBuilderClass.newInstance(), appId), false), context.getApplicationInfo().name), false));

            method0.invoke(TTAdSdkClass, context, configObj);

        } catch (Exception e) {
            e.printStackTrace();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值