黑马程序员:反射技术

----------------------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培训、期待与您交流! ----------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值