黑马程序员——Java基础 ---反射

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

                               反射

一:类的加载

  A:类的加载概述

     系统在运行程序的时候,会把.class文件加载到内存中,而编译期不会加载。。

       1,当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过

          加载,连接,初始化三步来实现对这个类进行初始化。

           1)加载:

               就是指将class文件读入内存,并为之创建一个Class对象,任何类被

               使用时系统都会建立一个Class对象。

           2)连接:

               验证 是否有正确的内部结构,并和其他类协调一致

               准备 负责为类的静态成员分配内存,并设置默认初始化值

               解析 将类的二进制数据中的符号引用替换为直接引用

           3)初始化:

                就是我们以前的初始化步骤

  

  B:类的加载时机

      1,创建类的实例

      2,访问类的静态变量,或者为静态变量赋值 Person.country =”中国”;

      3,调用类的静态方法 Person.show( );

      4,使用反射方式类强制创建某个类或接口对应的java.lang.Class对象

      5,初始化某个类的子类 Fu Zi

      6,直接使用java.exe 命令来运行某个主类 main

          

二:类的加载器  

A:类的加载器的概述

    负责将.class文件加载到内存中,并为之生成对应的Class对象,

    虽然我们不需要关心类加载机制,但是了解这个机制我们就能

    更好的理解程序的运行。

B:类加载器的分类

          Bootstrap ClassLoader 根类加载器

         Extension ClassLoader 扩展类加载器

         Sysetm ClassLoader 系统类加载器

C:类加载器的作用

      1Bootstrap

            Bootstrap ClassLoader 根类加载器

              也被称为引导类加载器,负责java核心类的加载

              比如:SystemString等,在JRElib目录下rt.jar文件中

      2Extension

            Extension ClassLoader 扩展类加载器

               负责JRE的扩展目录中jar包的加载

               在JDKJRElib目录下ext目录

      3Sysetm

            Sysetm ClassLoader 系统类加载器

               负责在JVM启动时加载来自java命令的class文件

               以及classpath环境变量所指定的jar包和类路径

 

三:反射

   A:反射的概述

         1java反射机制是在运行状态中

                对于任意一个类,都能够知道这个类的所有属性和方法。

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

        2,这种动态(运行时)获取的信息以及动态调用对象的方法的功能称为

                Java语言的反射机制。(反向的获取和调用)

   B:反射机制的作用

        1,反编译:.class-->.java

        2,通过反射机制访问java对象的属性,方法,构造方法等;

  C:反射机制中的类

      java.lang.Class;                

      java.lang.reflect.Constructor; java.lang.reflect.Field;        

      java.lang.reflect.Method;

      java.lang.reflect.Modifier;

    Class对戏那个可以获得该类里的方法, 构造器和Field, 这三个累都位于java.lang.reflect包下, 并实现了java.lang.reflect.Member接口. 

创建对象

通过反射生成对象的两种方式: 
  1. 使用Class对象的newInstance()方法. 需要Class对象对应的类有默认构造器, 儿执行newInstance()方法就是利用默认构造器创建该类的实例. 
  2. 使用Class对象获得指定的Constructor对象, 再调用Constructor对象的newInstructor()方法创建该Class对象对应类的实例. 

调用方法

1, 通过Class对象的getMethods()或getMethod()方法能获得全部或指定方法. 
 
2,Method类有个invoke()方法, 用以调用指定对象的方法:
    Object invoke(Object obj, Object... args): obj是执行该方法的主调, args是执行时传入该方法的实参. 
 
3,当通过Method的invoke()方法调用对应方法时, Java会要求程序必须有调用该方法的权限. 如果程序需要调用private方法, 可以先调用Method对戏那个的setAccessible方法:
     setAccessible(boolean flag): true表示该Method在使用时应该取消访问权检查, false表示要检查. 
 
4,setAccessible()方法继承自Method的父类AccessibleObject, Constructor和Field类也可以调用该方法. 
 
访问属性值
1, 通过Class对象的getFields()或getField()方法能获得全部或指定Field. 
 
2,Field类量两个方法: 
  1. getXxx(Object obj): 获取obj对象该Field的属性值. 此处Xxx对应8个基本类型, 如果该属性的类型是引用类型, 则取消get后面的Xxx. 
  2. setXxx(Object obj, Xxx val): 将obj对象的该属性值设为val. 此处Xxx对应8个基本类型, 如果该属性的类型是引用类型, 则取消get后面的Xxx. 

操作数组

1 , java.lang.reflect包下还提供了一个Array类, Array对象可以代表所有的数组. 程序可以通过Array动态地创建数组, 操作数组元素. 
 
2,Array的方法: 
  1. static Object newInstance(Class<?> componentType, int... length): 创建一个据有偶指定的元素类型, 指定维度的新数组. 
  2. Static xxx getXxx(Object array, int index): 返回array数组中的第index个元素. 如果数组元素是引用类型, 则该方法变为get(Object array, int index). 
  3. static void setXxx(Object array, int index, xxx val): 将array数组的第index个元素设为val.  如果数组元素是引用类型, 则该方法变为get(Object array, int index, xxx val). 
 

 

 D:具体功能实现

例(1)

  1.获取.class文件的对象
  2.调用该对象方法 newInstance

 

 

 1 public class Demo1_Constructor {
 2     @SuppressWarnings("unchecked")
 3     public static void main(String[] args) throws Exception {
 4 
 5         // 1 获取.class对象
 6         Class clz = Class.forName("cn.itcast_bean.User");
 7 
 8         // 2.调用方法 , 获取有参的构造 ,就需要传递对应参数 .
 9         Constructor constructor = clz.getConstructor(String.class, int.class);
10 
11         Object u = constructor.newInstance("悟空", 800);
12 
13         System.out.println(u);
14 
15         User user = new User("三藏", 500);
16 
17         System.out.println(user);
18 
19     }
20}

 

 例(2)

 1.获取.class文件的对象
 2.调用该对象方法 getFiled

Field
 Object get(Object obj) 返回指定对象上此 Field 表示的字段的值

 1 public class Demo2_Filed {
 2     public static void main(String[] args) throws Exception {
 3         // 1 获取.class对象
 4         Class clz = Class.forName("cn.itcast_bean.User");
 5 
 6         User u1 = new User("悟空", 800);
 7         User u2 = new User("三藏", 500);
 8         // 2.调用方法
 9         Field field = clz.getField("id"); // 把id字段 变成 Filed对象
10         Object object = field.get(u1); // 获取某一个对象的该字段的值
11         System.out.println(object);
12 
13         // 获取 age
14         Field field2 = clz.getDeclaredField("age"); // 暴力获取    
15         field2.setAccessible(true);  // 打开权限   
16         Object object2 = field2.get(u2); // 获取 字段 值  
17         System.out.println(object2);
18 
19     }
20 }

例(3)

1.定义 User 类
2.Class.forName( ".....");
3.Method m = clz.getMethod();
4.执行

 1 public class Demo3_Method {
 2     @SuppressWarnings("unchecked")
 3     public static void main(String[] args) throws Exception {
 4         // 获取 .class文件的对象
 5 
 6         Class clz = Class.forName("cn.itcast_bean.User");
 7         // 创建出来 对象
 8         User u1 = new User("悟空", 800);
 9         // 获取 Method 对象
10         Method m = clz.getMethod("run"); // run 就是 方法名字 , 后面的 就是 run 方法的参数 ,没有参数
11                                             // 就 不传
12 
13         // m.invoke(new User());// 运行 run
14         m.invoke(u1); // 运行 u1的 run
15 
16         // 获取私有方法
17         Method sleep_method = clz.getDeclaredMethod("sleep");
18         sleep_method.setAccessible(true);
19         sleep_method.invoke(u1);
20 
21     }
22 }

例(4)

ArrayList<String>    添加一个数字   

 1 public class Demo4_Generic {
 2     @SuppressWarnings("unchecked")
 3     public static void main(String[] args) throws Exception {
 4         ArrayList<String> al = new ArrayList<>();
 5 
 6         al.add("aaa");
 7         al.add("bbb");
 8         al.add("ccc");
 9         al.add("dd");
10 
11         // al.add(123); // 通过泛型 ,来限制你存储 .但是 泛型这个 东西 ,在.class文件 ,会被擦除 .
12         System.out.println(al);
13 
14         // 通过反射技术 ,往 al 添加 123
15         // 获取 .class 文件对象
16         // Class.forName("java.util.ArrayList");
17         Class clz = al.getClass();
18 
19         // 获取 add 方法的method 对象
20         Method add_mehtod = clz.getDeclaredMethod("add", Object.class);
21         add_mehtod.setAccessible(true);
22 
23         // method对象 invoke
24         add_mehtod.invoke(al, 123);
25         System.out.println(al);
26     }
27 }

 

 

 

 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 

转载于:https://www.cnblogs.com/hmchengxuyuan/p/5008654.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值