• 黑马程序员——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、反射的作用——框架

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

    我做的房子就是框架

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

  • 相关阅读:
    App架构师实践指南四之性能优化一
    App架构师实践指南三之基础组件
    App架构师实践指南二之App开发工具
    App架构师实践指南一之App基础语法
    Linux下阅读MHT文件
    What Is Docker & Docker Container ? A Deep Dive Into Docker !
    Difference between Docker Image and Container?
    RabbitMQ .NET/C# Client API Guide
    How RabbitMQ Works and RabbitMQ Core Concepts
    Message Queue vs Message Bus — what are the differences?
  • 原文地址:https://www.cnblogs.com/sunxlfree1206/p/4735453.html
Copyright © 2020-2023  润新知