Android开发---Android编程之Java反射
来源:互联网 发布:女留学生遇害 知乎 编辑:程序博客网 时间:2024/06/06 08:37
1.反射机制的定义
1.1 基本定义
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的
任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
然而在android中Google很多的类的某些方法不让第三方应用去调用,通过java反射机制能把这些隐藏方法获取出来并调用,三方
应用上我们就很方便的去用这些方法。例如,在Android开发当中杀死某个应用的服务和进程调用ActivityManager.forceStopPackage()
方法就非常方便。
1.2 具体含义
如果熟悉Android,那么你应该知道,Google不知出于什么原因,在系统源码中一些类或方法中经常加上“@hide”注释标记。它的作用是使这个方法或类在生成SDK时不可见,因此由此注释的东西,你在编译期是不可见的。这就出现了一些问题。一些明明可以访问的东西编译期却无法访问了!这使得你的程序有些本来可以完成的功能无法编译通过。当然,有一种办法是自己去掉Android源码中的所有“@hide”标记,然后重新编译一份自己的SDK。另一种办法就是使用Java反射机制。
如果你使用Java,那么你应该知道Java中有一个Class类。Class类本身表示Java对象的类型,我们可以通过一个Object(子)对象的getClass方法取得一个对象的类型,此函数返回的就是一个Class类。当然,获得Class对象的方法有许多,但是没有一种方法是通过Class的构造函数来生成Class对象的。(参考网址:http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html)
----------------------------------------------------------------------------------------------------------------------------
获取一些基本信息
在我们得到一个类的Class类对象之后,Java反射机制就可以大展拳脚了。
2.Java类反射中所必须的类:
Java的类反射所需要的类并不多,它们分别是:Field、Constructor、Method、Class、Object。下面,我将对这些类做一个简单的说明。
------------------------------------------------------------------------------------------------------------------------------
Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把 它看成为一个封装反射类的属性的类。
Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性。而 Constructor类则封装了反射类的构造方法。
1) 得到某个类的所有构造方法为:
Constructor [] constructors = Class.forName("java.lang.String").getConstructors();
2) 得到某一个构造方法:
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
Method类:提供关于类的接口上单独某个方法的信息。所反映的方法可能是类方法和实例方法(包括抽象方法)。这个类不难理解,它是用来
封装反射类的方法的一个类。
Class类:类的实例表示正在运行的java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class的一个类,
所有具有相同元素类型和维数的数组都共享该Class对象。
Object类:每个类都是使用Object类作为超类。所有对象(包括数组)都实现了这个类的方法。
创建实例对象的方法:
1)通常方式:String str=new String(new StringBuffer("abc"));
2)反射方式:String str=(String) constructor.newInstance(new StringBuffer("abc"));
----------------------------------------------------------------------------------------------------------------------------
代码示例一:
package com.example.reflect;
public class ReflectTest {
public static void main(String[] args) throws Exception{
String str1="abc";
Class class1=str1.getClass();
Class class2=String.class;
Class class3=Class.forName("java.lang.String");
System.out.println(class1 == class2);
System.out.println(class1 == class3);
}
}
测试结果:
true
true
=================================================================================
3.关于属性Field类的使用举例论证
-----------------------------------------------------------------------------------------------------------------------------------------------
package com.example.reflect;
public class User {
private int width,height;
private int table=3;
public int area;
public String name;
protected float angle;
public User(int width,int height){
this.width=width;
this.height=height;
}
public int add(int a,int b){
return a+b;
}
}
测试代码:
package com.example.reflect;
import java.lang.reflect.Field;
public class ReflectTest {
public static void main(String[] args) throws Exception{
User user=new User(3,4);
Class userClass=user.getClass(); //获取到User类的Class对象
try{
System.out.println("反射类中类的public类型变量的返回值类型");
System.out.println("-----------------------");
Field[] fieldType=userClass.getFields(); //public 类型
for(int i=0;i<fieldType.length;i++){
Class fieldClass=fieldType[i].getType();
System.out.println("返回值:"+fieldClass);
}
System.out.println("------------------------");
System.out.println("反射类中类的成员变量的所有属性返回值类型");
Field[] field=userClass.getDeclaredFields(); //private、protected、public
for(int i=0;i<field.length;i++){
Class fieldClass=field[i].getType();
System.out.println("返回值:"+fieldClass);
}
System.out.println("------------------------");
System.out.println("反射类中私有属性的值");
//获取private类型的变量值
Field privateField=userClass.getDeclaredField("table");
privateField.setAccessible(true);
Integer i= (Integer)privateField.get(user);
System.out.println(i);
}catch(Exception e){
e.printStackTrace();
}
}
}
测试结果:
反射类中类的public类型变量的返回值类型
----------------------------------------
返回值:int
返回值:class java.lang.String
----------------------------------------
反射类中类的成员变量的所有属性返回值类型
返回值:int
返回值:int
返回值:int
返回值:int
返回值:class java.lang.String
返回值:float
----------------------------------------
反射类中私有属性的值
table=3
============================================================
4.关于构造方法Constructor类的使用举例
--------------------------------------------------------------------------------------------------------------
package com.example.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectTest {
public static void main(String[] args) throws Exception{
User user=new User(3,4);
printConstructor(user);
}
public static void printConstructor(User u){
Class object=u.getClass(); //获取到Class对象
//获取指定类的类名称
String className=object.getName();
try{
Constructor[] theConstructors=object.getConstructors();
for(int i=0;i<theConstructors.length;i++){
Class[] parameterTypes=theConstructors[i].getParameterTypes();
System.out.println(className+"(");
for(int j=0;j<parameterTypes.length;j++){
System.out.println(parameterTypes[j].getName()+" ");
}
System.out.println(")");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
测试结果如下:
com.example.reflect.User(
int
int
)
===========================================================
5.反射类的方法的获取,即Method类的使用:
------------------------------------------------------------------------------------------------------------------------------------------------
一般获取成员方法为:
Method getMethod(String name, Class[] params)
Method[] getMethods()
Method getDeclaredMethod(String name, Class[] params)
Method[] getDeclaredMethods()
1、getDeclaredMethods和getMethods的区别
Method getDeclaredMethod(String name, Class... parameterTypes) : Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object.
Method[] getDeclaredMethods() : Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object.
由此可见,getDeclaredMethod*()获取的是类自身声的所有方法,包含public、protected和private方法。getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。
注意:因此用反射调用私有方法,必须用getDeclaredMethod方法,同时注意调用私有方法和改变私有变量一样,必须在调用前设置 method.setAccessible(true),这就是传说中的暴力反射吧!另外注意的一点如果是boolean型的参数,得到方法的时候需要用boolean.class或者Boolean.TYPE,不能用Boolean.class。
得到方法的时候可以用Method.toString()方法,打印出函数的完整原型,如protected java.lang.String com.unity3d.player.UnityPlayer.getCPUType();
---------------------------------------------------------------------------------------------------------------------------------------------------------
代码示例:
package com.example.reflect;
public class User {
private int width,height;
private int table=3;
public int area;
public String name;
protected float angle;
public User(int width,int height){
this.width=width;
this.height=height;
}
private int add(int a,int b){
return a+b;
}
}
测试代码:
package com.example.reflect;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Exception{
User user=new User(3,4);
printMemberFunction(user);
}
public static void printMemberFunction(Object user){
Class object=user.getClass();
//获取指定类的类名称
String className=object.getName();
try{
//获取方法的转化方法,参数,转化为Method类型
Method method=object.getDeclaredMethod("add", int.class,int.class);
//同上面的方法等同
Method method=object.getDeclaredMethod("add", Integer.TYPE,Integer.TYPE);
System.out.println(method.toString());
method.setAccessible(true); //私有方法必须要使用这样一条语句
int result=(Integer)method.invoke(user, 2,3); //使用反射的方法调用相应的方法
System.out.println(result);
}catch(Exception e){
e.printStackTrace();
}
}
}
打印结果为:
private int com.example.reflect.User.add(int,int)
5
--------------------------------------------------------------------------------------------------------------------------------------------------
- Android开发---Android编程之Java反射
- android编程之JAVA反射机制
- Android开发之XML反射
- Android插件化开发基础之Java反射机制研究
- Android开发学习笔记之反射技术
- Android开发之反射与注解
- Android开发之反射与注解
- Android开发之反射与注解
- Android开发之反射与注解
- Android开发之Socket编程
- Android开发之--脚本编程
- Android开发之Socket编程
- android开发之应用编程
- java开发之反射
- 【Android 应用开发】Android之Bluetooth编程
- Android基础之反射
- Java android 反射
- android开发之java的一些基础知识详解,java编程语法,扎实自己的android基本功
- ps/kill终止led进程
- 经典智力题【2】
- 多进程和多线程这件事
- [Drools]JAVA规则引擎 -- Drools
- 经典智力题【3】
- Android开发---Android编程之Java反射
- 发短信功能代码实现
- 经典智力题【4】海盗分金子问题的改进版
- [Drools]JAVA规则引擎2 -- Drools实例
- 经典智力题【5】排列组合题
- IOS之UITableView cell自定义视图中插入Tableview
- 云存储——Wuala
- 关于GCC的__attribute__(constructor)
- linux c++线程池的实现