JAVA反射机制定义:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。
一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
--------------------------------------------------------------------------
以上摘录自百度百科,在Android 中有很多类是被封闭的,比如 ServiceManager 蓝牙模块更是有N多个类被Android 隐藏不开放,要调用这些类必须使用java 的反射技术将类转为对象进行操作.Android 应用也是基于JAVA 语言为基础,当然也具备反射这一技术,下面我写了一个DEMO 是如何通过反射技术调用类名方法并完成一个加减乘除的记算器。
首先我们定义一个类,此为只是简单的定义几个方法,即加减乘除四个方法,代码如下:
class
operationClass {
public
float
add(
int
parm1,
int
parm2) {
return
parm1
+
parm2;
}
public
float
cut(
int
parm1,
int
parm2) {
return
parm1
-
parm2;
}
public
float
ride(
int
parm1,
int
parm2) {
return
parm1
*
parm2;
}
public
float
Except(
int
parm1,
int
parm2) {
return
parm1
/
parm2;
}
}
界面布局文件代码
<?
xml version="1.0" encoding="utf-8"
?>
<
LinearLayout
xmlns:android
="http://schemas.android.com/apk/res/android"
android:layout_width
="fill_parent"
android:orientation
="vertical"
android:layout_height
="fill_parent"
>
<
EditText
android:id
="@+id/EditText01"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
></
EditText
>
<
EditText
android:id
="@+id/EditText02"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
></
EditText
>
<
TextView
android:id
="@+id/TextView01"
android:layout_gravity
="center"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
TextView
>
<
LinearLayout
android:id
="@+id/LinearLayout01"
android:orientation
="horizontal"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
>
<
Button
android:text
="+"
android:id
="@+id/Button01"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
Button
>
<
Button
android:text
="-"
android:id
="@+id/Button02"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
Button
>
<
Button
android:text
="*"
android:id
="@+id/Button03"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
Button
>
<
Button
android:text
="/"
android:id
="@+id/Button04"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
Button
>
<
Button
android:text
="="
android:id
="@+id/Button05"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
></
Button
>
</
LinearLayout
>
</
LinearLayout
>
下面就是一些对反射技术的操作代码了,由于本篇是反射机制的入门篇,在此只是通过一个小DEMO 讲解反射的常用的几个方法,这里的流程如下:
- 获取相应的类对象名称
Class
<?>
classType
=
Class.forName(
"
com.terry.operationClass
"
);
如果知道类名并且类名存在于我们工程中,即jar 文件中包含可以使用如下写法
Class
<?>
classType
=
operationClass.
class
;
- 返回本类对象
Object invokeOperation
=
classType.newInstance();
- 根据类对象名称去查找对应的方法
Method addMethod
=
classType.getMethod(
"
add
"
,
new
Class[] {
int
.
class
,
int
.
class
});
参数一:代码需要查找类名的方法,参数二:指定查找方法的参数类型
- 调用查找 到的方法执行此方法的处理
Object result
=
addMethod.invoke(invokeOperation,
new
Object[] {
new
Integer(first),
new
Integer(second) });
通过调用查找到的方法即可实现方法体的功能。
Tip:反射比较耗费系统资源,建议不在不得以的情况下不要用,尤其是在移动设备上这种对资源要求十分苛刻的设备。
运行效果如下:
下面给出全部页面代码:
package
com.terry;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.EditText;
import
android.widget.TextView;
public
class
OperationActivity
extends
Activity {
private
EditText one, two;
private
TextView result;
private
Button add, cut, ride, Except, sum;
int
first, second;
String operaionFun
=
""
;
/**
Called when the activity is first created.
*/
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
findview();
add.setOnClickListener(click);
cut.setOnClickListener(click);
ride.setOnClickListener(click);
Except.setOnClickListener(click);
sum.setOnClickListener(click);
}
void
findview() {
one
=
(EditText) findViewById(R.id.EditText01);
two
=
(EditText) findViewById(R.id.EditText02);
result
=
(TextView) findViewById(R.id.TextView01);
add
=
(Button) findViewById(R.id.Button01);
cut
=
(Button) findViewById(R.id.Button02);
ride
=
(Button) findViewById(R.id.Button03);
Except
=
(Button) findViewById(R.id.Button04);
sum
=
(Button) findViewById(R.id.Button05);
}
OnClickListener click
=
new
OnClickListener() {
@Override
public
void
onClick(View v) {
//
TODO Auto-generated method stub
first
=
Integer.parseInt(one.getText().toString());
second
=
Integer.parseInt(two.getText().toString());
switch
(v.getId()) {
case
R.id.Button01:
operaionFun
=
"
+
"
;
break
;
case
R.id.Button02:
operaionFun
=
"
-
"
;
break
;
case
R.id.Button03:
operaionFun
=
"
*
"
;
break
;
case
R.id.Button04:
operaionFun
=
"
/
"
;
break
;
case
R.id.Button05:
try
{
result.setText(operation(operaionFun, first, second));
}
catch
(SecurityException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalArgumentException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(ClassNotFoundException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalAccessException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InstantiationException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(NoSuchMethodException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InvocationTargetException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
break
;
}
}
};
/**
* 操作方法
*
*
@param
oper
*
@param
first
*
@param
second
*
@return
*
@throws
ClassNotFoundException
*
@throws
IllegalAccessException
*
@throws
InstantiationException
*
@throws
SecurityException
*
@throws
NoSuchMethodException
*
@throws
IllegalArgumentException
*
@throws
InvocationTargetException
*/
String operation(String oper,
int
first,
int
second)
throws
ClassNotFoundException, IllegalAccessException,
InstantiationException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
//
获取相应的类对象名称
Class
<?>
classType
=
Class.forName(
"
com.terry.operationClass
"
);
//
如果知道类名并且类名存在于我们工程中,即jar 文件中包含可以使用如下写法
//
Class<?> classType = operationClass.class;
//
返回本类对象
Object invokeOperation
=
classType.newInstance();
if
(oper.equals(
"
+
"
)) {
//
根据类对象名称去查找对应的方法
Method addMethod
=
classType.getMethod(
"
add
"
,
new
Class[] {
int
.
class
,
int
.
class
});
//
调用查找 到的方法执行此方法的处理
Object result
=
addMethod.invoke(invokeOperation,
new
Object[] {
new
Integer(first),
new
Integer(second) });
return
result.toString();
}
else
if
(oper.equals(
"
-
"
)) {
Method cutMethod
=
classType.getMethod(
"
cut
"
,
new
Class[] {
int
.
class
,
int
.
class
});
Object result
=
cutMethod.invoke(invokeOperation,
new
Object[] {
new
Integer(first),
new
Integer(second) });
return
result.toString();
}
else
if
(oper.equals(
"
*
"
)) {
Method rideMethod
=
classType.getMethod(
"
ride
"
,
new
Class[] {
int
.
class
,
int
.
class
});
Object result
=
rideMethod.invoke(invokeOperation,
new
Object[] {
new
Integer(first),
new
Integer(second) });
return
result.toString();
}
else
if
(oper.equals(
"
/
"
)) {
Method execMthod
=
classType.getMethod(
"
Except
"
,
new
Class[] {
int
.
class
,
int
.
class
});
Object result
=
execMthod.invoke(invokeOperation,
new
Object[] {
new
Integer(first),
new
Integer(second) });
return
result.toString();
}
return
""
;
}
}
Tip:在JAVA中可以通过main 函数打印,在Android 好像调用会出错。