黑马程序员——java学习16(张孝祥)——反射

反射机制

在运行状态中,对于任意一个类,能知道它全部的方法和属性,

       对于任意一个对象,能能够调用它的任意一个方法和属性

就是把java类中的各种成分映射成相应的java类    

反射的基础Class

Class类的实例对象就是字节码,就是那个类被编译后形成的二进制数据代码

获取对象的方式为三种

1、类名.class

2、对象.getClass

3、Class.forName("类名")

 1 package learn;
 2 
 3 public class ReflectTest {
 4     public static void main(String[] args) throws Exception{
 5         String str1 = "abc";
 6         Class cls1 = str1.getClass();
 7         Class cls2 = String.class;
 8         Class cls3 = Class.forName("java.lang.String");
 9         System.out.println(cls1==cls2);//true
10         System.out.println(cls2==cls3);//true
11         //是否为基本类型字节码
12         System.out.println(cls1.isPrimitive());//false
13         System.out.println(int.class.isPrimitive());//true
14         System.out.println(int.class==Integer.class);//false
15         System.out.println(int.class==Integer.TYPE);//true  代表其所包装的基本类型的字节码
16         System.out.println(int[].class.isPrimitive()/*isArray为true*/);//false数组不是原始类型
17         
18     }
19 }

1、Constructor类——获得构造方法

  T  newInstance(Object... initargs) 

                  使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

 Class中也有,但是是无参的,而Constructor则可以使用有参,好用的多

1         Constructor con1 = String.class.getConstructor(StringBuffer.class);//源用class数组来作参数
2         //字节码强转字符串= new String(new StringBuffer("abc"));
3         String str2 = (String) con1.newInstance(new StringBuffer("abc"));
4         //输出第二个字符
5         System.out.println(str2.charAt(2));

2、Field类——获得成员变量

字节码用==比较

 1         changeStringValue(pt1);
 2         System.out.println(pt1);
 3     }
 4 
 5     private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
 6         //将类中所有成员取出,存入field数组中
 7         Field[] fields = obj.getClass().getFields();
 8         for(Field field :fields)
 9         {
10 //            if(field.getType().equals(String.class))因为字节码对象是唯一的
11             if(field.getType()==String.class)
12             {
13                 String oldValue = (String)field.get(obj);
14                 String newValue = oldValue.replace('b', 'a');
15                 //通过set方法来为对象重新赋值
16                 field.set(obj, newValue);
17             }
18             
19         }
20         
21     }
22 }

3、Method类——获得方法

当invoke方法传入的第一个参数为null时,表示静态方法

 1 //        TestArguments.main(new String[]{"111","222","333"});
 2         String startingClassName = args[0];
 3         Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
 4 //        mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
 5         //都是以防1.5的特性拆包
 6         mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
 7 
 8 
 9 class TestArguments{
10     public static void main(String[] args)
11     {
12         for(String arg: args)
13         {
14             System.out.println(arg);
15         }
16     }
17 }

4、数组中的反射

维数和元素类型相同的数组,则具有相同的class

 Class<? super T>  getSuperclass()            

返回这个方法的父类的字节码

 通过数组的字节码调用此方法,得到的是Object的字节码。

5、反射的作用——框架

做房子卖给客户,用户自己安装门窗,

我做的房子就是框架

工具类被用户的类调用,而框架则是调用用户提供的类

原文地址:https://www.cnblogs.com/sunxlfree1206/p/4735453.html