Java和Android反射使用记录

平时看源码经常会遇到反射的代码,这里记录下反射的用法,方便查阅。

首先在java中测试,创建父类Persion:

package com.invok;

public abstract class Person {

	String name = "";
	private int age = 0;
	public int fPubVar = 0;

	abstract void getPhone();

	public Person() {
		System.out.println("I am Farther");
	}

	int myAge() {
		return 50;
	}

	String myName() {
		return "Father";
	}

	public void callSun() {
		getPhone();
		priMethod(25);
	}

	private void priMethod(Integer a) {
		age = a;
		System.out.println("I am priMethod , Dont call me! age " + age);
	}

	/**
	 * @hide
	 */
	public void hideMethod(String name) {
		System.out.println("I am hideMethod , Dont call me! name:" + name
				+ "   age:" + age);
	}
}
子类Man:

package com.invok;

import java.util.Observable;
import java.util.Observer;

public class Man extends Person implements Observer {

	private int age = 0;
	private String var1 = "I am var1";
	public int var2 = 20;

	public Man() {
		System.out.println("I am Man" + var1);
		age = 20;
	}

	public int myAge() {
		return 28;
	}

	public String myName() {
		return "Jerome";
	}

	private void getName() {
		System.out.println("I am Jerome");
	}

	/**
	 * @hide
	 */
	private void getAge() {
		System.out.println("I am " + age);
	}

	@Override
	void getPhone() {
		System.out.println("I am sun , My age is " + age + "___" + var2);
	}

	@Override
	public void update(Observable o, Object arg) {

	}
}
获取属性和方法测试如下:

	static void getInfo() {
		Man r = new Man();
		Class<?> temp = r.getClass();
		try {
			System.out.println("获取反射类中所有公有的属性");
			Field[] fb = temp.getFields();
			for (int j = 0; j < fb.length; j++) {
				Class<?> cl = fb[j].getType();
				System.out.println("getFields:" + cl + "___" + fb[j].getName());
			}
			System.out.println("获取反射类中所有的属性");
			Field[] fa = temp.getDeclaredFields();
			for (int j = 0; j < fa.length; j++) {
				Class<?> cl = fa[j].getType();
				System.out.println("getDeclaredFields:" + cl + "____" + fa[j].getName());
			}

			System.out.println("获取反射类中所有的方法");
			Method[] fm = temp.getMethods();
			for (int i = 0; i < fm.length; i++) {
				System.out.println("getMethods:" + fm[i].getName() + "____"
						+ fm[i].getReturnType().getName());
			}

			System.out.println("获取反射类中所有的接口");
			Class<?>[] fi = temp.getInterfaces();
			for (int i = 0; i < fi.length; i++) {
				System.out.println("getInterfaces:" + fi[i].getName());
			}

			System.out.println("获取反射类中私有属性的值");
			Field f = temp.getDeclaredField("var1");
			f.setAccessible(true);
			String i = (String) f.get(r);
			System.out.println(i);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
打印结果:

I am Farther
I am ManI am var1
获取反射类中所有公有的属性
getFields:int___var2
getFields:int___fPubVar
获取反射类中所有的属性
getDeclaredFields:int____age
getDeclaredFields:class java.lang.String____var1
getDeclaredFields:int____var2
获取反射类中所有的方法
getMethods:myAge____int
getMethods:myName____java.lang.String
getMethods:update____void
getMethods:hideMethod____void
getMethods:callSun____void
getMethods:wait____void
getMethods:wait____void
getMethods:wait____void
getMethods:equals____boolean
getMethods:toString____java.lang.String
getMethods:hashCode____int
getMethods:getClass____java.lang.Class
getMethods:notify____void
getMethods:notifyAll____void
获取反射类中所有的接口
getInterfaces:java.util.Observer
获取反射类中私有属性的值
I am var1

下面测试父类变量和父类方法:
	/**
	 * 修复父类变量,调用父类方法
	 */
	static void callSpuerMethod() {
		Man r = new Man();
		try {
			// 修改私有变量;
			Field f = r.getClass().getSuperclass().getDeclaredField("age");
			f.setAccessible(true);
			f.set(r, 20);

			// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
			Method mp = r.getClass().getSuperclass()
					.getDeclaredMethod("priMethod", Integer.class);
			mp.setAccessible(true);
			mp.invoke(r, 18);

			// 调用隐藏方法
			Method m = r.getClass().getSuperclass()
					.getMethod("hideMethod", String.class);
			m.setAccessible(true);
			m.invoke(r, "Jerome");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
打印结果:
I am Farther
I am ManI am var1
I am priMethod , Dont call me! age 18
I am hideMethod , Dont call me! name:Jerome   age:18

下面测试子类变量和方法:

	/**
	 * 修复子类变量,调用子类方法
	 */
	static void callCurrentMethod() {
		Man r = new Man();
		try {
			// 修改私有变量;
			Field f = r.getClass().getDeclaredField("age");
			f.setAccessible(true);
			f.set(r, 21);

			// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
			Method mp = r.getClass().getDeclaredMethod("getName");
			mp.setAccessible(true);
			mp.invoke(r);

			// 调用隐藏私有方法
			Method m = r.getClass().getDeclaredMethod("getAge");
			m.setAccessible(true);
			m.invoke(r);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
打印结果:
I am Farther
I am ManI am var1
I am Jerome
I am 21


下面看下用Class.forName加载类及实例化:

	/**
	 * 用Class.forName加载类及实例化
	 */
	static void callOtherMethod() {
		try {
			// Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象
			// Class.forName(xxx.xx.xx) 的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
			Class<?> cl = Class.forName("com.invok.Man");
			Object r = cl.newInstance();

			// 修改私有变量;
			Field f = cl.getDeclaredField("age");
			f.setAccessible(true);
			f.set(r, 20);

			// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
			Method mp = cl.getDeclaredMethod("getName");
			mp.setAccessible(true);
			mp.invoke(r);

			// 调用隐藏私有方法
			Method m = cl.getDeclaredMethod("getAge");
			m.setAccessible(true);
			m.invoke(r);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

打印结果:
I am Farther
I am ManI am var1
I am Jerome
I am 20

下面看下android上的用法:

	private void invorkTest() {
		TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		try {
			Method method =  mTelephonyManager.getClass().getDeclaredMethod("hasIccCard", int.class);
			boolean hasIccCard = (Boolean)method.invoke(mTelephonyManager, 0);
			Log.d("test", "hasIccCard = " + hasIccCard);
			
			Method method1 =  mTelephonyManager.getClass().getDeclaredMethod("getSimState", int.class);
			int simState = (Integer)method1.invoke(mTelephonyManager, 0);
			Log.d("test", "simState = " + simState);
			
			Method method2 =  mTelephonyManager.getClass().getDeclaredMethod("getImei", int.class);
			String imei = (String)method2.invoke(mTelephonyManager, 0);
			Log.d("test", "imei = " + imei);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
上面通过反射获取手机是否有SIM卡,和获取SIM卡状态,和手机IMEI。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值