• java反射


     1 public class Test {
     2     /**
     3      * 1.在面相对象的世界里,万事万物皆对象
     4      *     类是对象,每一个类都是java.lang.Class类的对象
     5      * 
     6      * */
     7     @SuppressWarnings({ "rawtypes", "unused" })
     8     public static void main(String[] args) {
     9         //有一个类Test02.java,实例对象如何表示
    10         Test02 t2 = new Test02();
    11         //Test02这个类也是一个实例对象,Class类的实例对象,如何表示呢
    12         //任何一个类都是Class类的实例对象,有三种表示方式
    13         //第一种表示方式,表明任何一个类都有一个隐含的静态成员变量
    14         Class c1 = Test02.class;
    15         //第二种表达方式,已经知道该类的对象,通过getClass()
    16         Class c2 = t2.getClass();
    17         /*官网说 c1,c2表示Test02类的类类型(class type)
    18           t2是Test02类型;c1,c2是Class类型,Test02是Class类型
    19               万事万物皆对象,类也是对象,是Class的实例对象,这个对象我们称为该类的类类型
    20         */
    21         //不管c1 or c2都代表了Test02类的类类型,一个类只可能是Class类的一个实例对象
    22         System.out.println(c1==c2);//true
    23         //第三种表达方式
    24         /**
    25          * Class.forName("com.wzy.FanSe.Test02")
    26          * 不仅表示了类的类类型,还代表了动态加载类
    27          * New创建对象,是静态加载类,在编译时就需要加载所有的可能使用到的类
    28          *    动态加载类,在运行时刻加载
    29          * 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类
    30          * Public static void main(String [] args){
    31             动态加载类,在运行时刻加载,
    32             在一些软件更新时用到,可以免去已经编译好的重新编译,只需把新的代码编译就行
    33             Class c = Class.forName(args[0]);
    34             创建对象
    35             c.newInstance();
    36             }
    37          */
    38         try {
    39             
    40             Class c3 = Class.forName("com.wzy.FanSe.Test02");
    41             System.out.println(c2==c3);//true
    42         } catch (ClassNotFoundException e) {
    43             e.printStackTrace();
    44         }
    45         //我们可以通过该类的类类型创建该类的对象实例,即通过c1,c2,c3创建Test02的实例对象
    46         try {
    47             Test02 test02 =(Test02)c1.newInstance();//需要有无参数的构造方法
    48             test02.print();
    49         } catch (InstantiationException e) {
    50             e.printStackTrace();
    51         } catch (IllegalAccessException e) {
    52             e.printStackTrace();
    53         }
    54         System.out.println("ClassUtil类测试-----------");
    55         String s = "hello";
    56         //ClassUtil.printClassMessage(s);
    57         int a = 0;
    58         //ClassUtil.printClassMessage(s);
    59         ClassUtil.printConMessage("hello");
    60     }
    61 }
    View Code
     1 /**
     2  * 打印类的信息,包括类的成员函数、成员变量
     3  * obj该对象所属类的信息
     4  * */
     5 @SuppressWarnings("unused")
     6 public class ClassUtil {
     7     @SuppressWarnings("rawtypes")
     8     public static void  printClassMessage(Object obj){
     9         //要获取类的信息,首先要获取类的类类型
    10         Class c = obj.getClass();
    11         //获取类的名称
    12         System.out.println(c.getName());
    13         /**获取成员函数信息  
    14          *一个成员方法就是一个Method对象
    15          *getMethods()方法获取的是所有的public的函数,包括父类继承来的
    16          *getDeclaredMethods()获取的是该类自己声明的方法,不问访问权限 */
    17         Method[] ms = c.getMethods();//c.getDeclaredMethods();
    18         for(int i=0;i<ms.length;i++){
    19             //得到方法的返回值类型的类类型
    20             Class returnType = ms[i].getReturnType();
    21             System.out.print(returnType.getName()+"  ");
    22             //得到方法的名称
    23             System.out.print(ms[i].getName()+"(");
    24             //获取参数类型,得到的是参数列表的类型的类类型
    25             Class[] paramTypes = ms[i].getParameterTypes();
    26             for (Class class1 : paramTypes) {
    27                 System.out.print(class1.getName()+",");
    28             }
    29             System.out.println(")");
    30         }
    31         /**获取成员变量信息
    32          *成员变量也是对象
    33          *java.lang.reflect.Field
    34          *Field类封装了关于成员变量的操作
    35          *getFields()方法获取的是所有的public的成员变量的信息
    36          *getDeclaredFields()获取的是该类自己声明的成员变量的信息 */
    37         //Field[] fs = c.getFields();
    38         Field[] fs = c.getDeclaredFields();
    39         for(Field field : fs){
    40             //得到成员变量的类型的类类型
    41             Class fieldType = field.getType();
    42             String typeName = fieldType.getName();
    43             //得到成员变量的名称
    44             String fieldName = field.getName();
    45             System.out.println(typeName+"  "+fieldName);
    46         }
    47     
    48     }
    49     /**
    50      * 打印对象的构造函数信息*/
    51     @SuppressWarnings("rawtypes")
    52     public static void printConMessage(Object obj){
    53         Class c = obj.getClass();
    54         /*
    55          * 构造函数也是对象
    56          * java.lang.Constructor中封装了构造函数的信息
    57          * getConstructors()获取所有的public的构造函数
    58          * getDeclaredConstructors()获取自己声明的构造函数*/
    59         //Constructor[] cs = c.getConstructors();
    60         Constructor[] cs = c.getDeclaredConstructors();
    61         for (Constructor constructor : cs) {
    62             //得到构造函数的名字
    63             System.out.print(constructor.getName()+"(");
    64             //获取构造函数的参数列表,得到的是参数列表的类类型
    65             Class[] paramTypes = constructor.getParameterTypes();
    66             for (Class class1 : paramTypes) {
    67                 System.out.print(class1.getName());
    68             }
    69             System.out.println(")");
    70         }
    71     }
    72 
    73 }
    View Code
     1 public class Test03 {
     2     @SuppressWarnings({ "rawtypes", "unused", "unchecked" })
     3     public static void main(String[] args) {
     4         Class c1 = int.class;//int类的类类型
     5         Class c2 = String.class;//String类的类类型
     6         Class c3 = double.class;
     7         Class c4 = Double.class;
     8         Class c5 = void.class;
     9         System.out.println(c5.getName());//void
    10         System.out.println(c2.getName());//java.lang.String
    11         System.out.println(c2.getSimpleName());//String
    12         
    13         /**方法反射的基本操作*/
    14         //1.要获取一个方法就是获取类的信息,获取类的信息就是首先要获取类的类类型
    15         Testt t = new Testt();
    16         Class c = t.getClass();
    17         /*
    18          * 2.获取方法,名称和参数类决定
    19             getMethod获取的是public方法
    20             getDeclaredMethod获取的是自己声明的方法*/
    21         
    22         //Method m = c.getMethod("print",new Class[]{int.class,int.class});
    23         //Method m = c.getMethod("print",int.class,int.class);
    24         try {
    25             Method m = c.getDeclaredMethod("print",new Class[]{int.class,int.class});
    26             //调用方法t.print(10,1);
    27             
    28             //方法的反射操作是用m对象来进行方法调用和t.print(10,1)效果相同
    29             //方法如果没有返回值,返回null;有的话返回
    30             Object o = m.invoke(t,10,2);//new Object[]{10,5}//t.print(10,1)
    31             
    32             Method m1 = c.getDeclaredMethod("print", String.class,String.class);
    33             m1.invoke(t,"hel","lo");//HELlo
    34             Method m2 = c.getDeclaredMethod("print");
    35             m2.invoke(t);//hehhahah
    36         } catch (Exception e) {
    37             e.printStackTrace();
    38         } 
    39     }
    40 }
    41 class Testt{
    42     public void print(){
    43         System.out.println("hehhahah");
    44     }
    45     public void print(int a,int b){
    46         System.out.println(a+b);
    47     }
    48     public void print(String a,String b){
    49         System.out.println(a.toUpperCase()+b);
    50     }
    51 }
    View Code
     1 public class Test04 {
     2     @SuppressWarnings({ "rawtypes", "unchecked" })
     3     public static void main(String[] args) {
     4         ArrayList list = new ArrayList();
     5         ArrayList<String> list01 = new ArrayList<String>();
     6         Class c1 = list.getClass();
     7         Class c2 = list01.getClass();
     8         System.out.println(c1==c2);//true
     9         /**
    10          * 反射的操作都是编译之后的操作
    11          * 说明编译之后集合的泛型是去泛型化的
    12          * java中集合的泛型是防止错误输入的,只在编译阶段有效,绕过编译就无效了
    13          * 我们可以通过方法的反射来操作,绕过编译*/
    14         try {
    15             Method m = c1.getMethod("add", Object.class);
    16             m.invoke(list01, 100);//把int型的数据插入了ArrayList<String>内
    17             System.out.println(list01.size());
    18         //    System.out.println(list01.get(0));
    19         } catch (Exception e) {
    20             e.printStackTrace();     
    21         }
    22     }
    23 }
    View Code
  • 相关阅读:
    引用传参
    VS2017 用MySQL Connector 链接 MySQL时 getString异常问题
    Matlab学习日记第3天
    Matlab学习日记第2天
    Matlab学习日记第1天
    c#加密解密方法
    DataGridView添加行号
    c#带参数数组链接数据库方法
    2021/5/27
    2021/5/14
  • 原文地址:https://www.cnblogs.com/wwzyy/p/4991458.html
Copyright © 2020-2023  润新知