----------------------android培训、java培训、期待与您交流! ----------------------
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
反射:
* 反射:构造器的过程
* 反射:解析成员方法的过程
* 反射:解析成员属性的过程
1.1 java类反射中的主要方法
对于以下三类组件中的任何一类来说 -- 构造函数、字段和方法 -- java.lang.Class 提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射调用:
Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors() -- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)
获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:
Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段
用于获得方法信息函数:
Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods() -- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods() -- 获得类声明的所有方法
对其中一些函数还是有所应用的,废话少说,直接程序。
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo {
@SuppressWarnings("unchecked")
public static void main(String[] args){
//模拟new String(new StringBuffer("abc");
try {
String str1="abc";
Constructor constructor =
String.class.getConstructor(StringBuffer.class);//可变参数传递,作为构造函数类的对象
//只知道其为一个构造方法,不知道是什么类型的构造方法
try {
String str= (String)constructor.newInstance(new StringBuffer("abc"));//用一个StringBuffer传递给这个
System.out.println(str.charAt(0));
/*----------------------------------------------------*/
ReflectPoint point=new ReflectPoint(3,5);
try {
Field fieldY=point.getClass().getField("y");//获取其自解码,然后再获取其字段
System.out.println(fieldY.get(point));//获取point对象的那个值,fieldY不是对象身上的变量,是类上的,要用他去取某个对象的值
Field fieldX=point.getClass().getDeclaredField("x");//获取其自解码,然后再获取其字段
fieldX.setAccessible(true);//暴力反射
System.out.println(fieldX.get(point));//获取point对象的那个值,fieldX不是对象身上的变量,是类上的,要用他去取某个对象的值
/*---------------------------------------------------*/
ChageBToA chagebtoa=new ChageBToA();
changeStringValue(chagebtoa);
System.out.println(chagebtoa);
Method methodcharAt=String.class.getMethod("charAt",int.class);//指调用charAt方法,传递一个int类型的数作为参数
System.out.println(methodcharAt.invoke(str1, 1));//指调用str1的第二个字符,1.5的语法
System.out.println(methodcharAt.invoke(str1, new Object[]{2}));//按1.4的语法调用
TestArguments.main(new String[]{"111","2222","33333"});//静态main方法调用
String startingClassName=args[0];//假设传递进去的第一个参数就是类名
try {
Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class);//获取传进来那个类的方法
mainMethod.invoke(null,(Object)new String[]{"111","2222","33333"});//静态的所以不用传递对象实例
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
//将ChageBToA中B转换成A
private static void changeStringValue(Object obj) {//传入一个对象
Field[] fields=obj.getClass().getDeclaredFields();//获取这个对象的所有字段
for(Field field: fields){
if(field.getType()==String.class){//自解码为一份
try {
String oldValue=(String) field.get(obj);
String newValue=oldValue.replace("b", "a");
field.set(obj, newValue);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
class TestArguments{
public static void main(String[] args){
for(String arg:args){
System.out.println(arg);
}
}
}
package reflect;
public class ChageBToA {
public String str1="ball";
public String str2="basketball";
public String str3="itcast";
@Override
public String toString() {
return str1+"::"+str2+"::"+str3;
}
}
通过上述注解,应该可以理解反射的应用范围了吧。可不可以早睡点啊,早上上班,晚上还要java基础,猿类伤不起啊啊啊啊啊。。。。。
----------------------android培训、java培训、期待与您交流! ----------------------