• JAVA反射学习


    1.Class类

     1 package com.hxy;
     2 
     3 class Foo{}
     4 
     5 public class Reflect 
     6 {
     7     public static void main(String[] args) 
     8     {
     9         //1.获取Class对象
    10         Class c1 = Foo.class;
    11         
    12         Class c2 = new Foo().getClass();
    13         
    14         Class c3 = null;
    15         try 
    16         {
    17             c3 = Class.forName("com.hxy.Foo");
    18         } 
    19         catch (ClassNotFoundException e) 
    20         {
    21             e.printStackTrace();
    22         }
    23         
    24         System.out.println(c1 == c2);
    25         System.out.println(c2 == c3);    
    26         //true
    27         //true
    28         
    29         //2.通过类的Class对象创建该类实例
    30         try 
    31         {
    32             //调用newInstance方法需要Foo类有无参数的构造方法
    33             Foo foo1 = (Foo) c1.newInstance();
    34         } 
    35         catch (InstantiationException e) 
    36         {
    37             e.printStackTrace();
    38         } catch (IllegalAccessException e) 
    39         {
    40             e.printStackTrace();
    41         }
    42         
    43         //3.动态加载类
    44         
    45         //编译时刻加载类是“静态加载类”
    46         //运行时刻加载类是“动态加载类”
    47         
    48         //new创建对象是“静态加载类”,编译时刻就需要加载所有可能使用的类,无论是否可能用到    
    49         
    50         //Class.forName("完整类名")是动态加载类,要动态加载的类会在运行时加载
    51         //好处:动态加载的类可以随意添加或者更改,而不需要编译此文件
    52         
    53         //基本数据类型也有对应的Class
    54         Class c4 = int.class;
    55         Class c5 = Integer.class;
    56         System.out.println(c4 == c5);
    57         //false
    58         
    59         //注:基本的数据类型和void都存在相应的Class对象
    60         Class c6 = void.class;
    61         
    62         //getName()获取类全称
    63         //getSimpleName获取不包含包名的类的名称
    64         System.out.println(c4.getName());
    65         System.out.println(c5.getName());
    66         System.out.println(c6.getName());
    67         //int
    68         //java.lang.Integer
    69         //void
    70     }
    71 }

    2.获取类的成员变量、方法以及构造函数信息

    ClassUtil.java:

     1 package com.hxy;
     2 import java.lang.reflect.Constructor;
     3 import java.lang.reflect.Field;
     4 import java.lang.reflect.Method;
     5 
     6 public class ClassUtil 
     7 {
     8     public static void printFieldMessage(Object obj)
     9     {
    10         Class c = obj.getClass();
    11         System.out.println("类的名称是:" + c.getName());
    12         System.out.println("获取成员变量列表:");
    13         //getFields()方法获取的是所有public的成员变量,包括继承而来的
    14         //getDeclaredFields()方法获取的是所有该类自己声明的成员变量,不论访问权限
    15         Field[] fields = c.getDeclaredFields();
    16         for(int i = 0; i < fields.length; i++)
    17         {
    18             Class fieldType = fields[i].getType();
    19             String typeName = fieldType.getName();
    20             String fieldName = fields[i].getName();
    21             System.out.println(typeName + " " + fieldName);
    22         }
    23         System.out.println("获取成员变量列表结束。");
    24     }
    25     
    26     public static void printMethodMessage(Object obj)
    27     {
    28         Class c = obj.getClass();
    29         System.out.println("类的名称是:" + c.getName());
    30         //getMethods()方法获取的是所有public的函数,包括继承而来的
    31         //getDeclaredMethods()方法获取的是所有该类自己声明的方法,不论访问权限
    32         Method[] methods = c.getMethods();
    33         System.out.println("获取方法列表:");
    34         for(Method m: methods)
    35         {
    36             Class returnType = m.getReturnType();
    37             System.out.print(returnType.getName() + " " + m.getName() + "(");
    38             Class[] paramTypes = m.getParameterTypes();
    39             for(int i = 0; i < paramTypes.length; i++)
    40             {
    41                 String info = paramTypes[i].getName();
    42                 if(i != paramTypes.length - 1)
    43                 {
    44                     info = info + ", ";
    45                 }
    46                 System.out.print(info);
    47             }
    48             System.out.println(")");
    49         }
    50         System.out.println("获取方法列表结束。");
    51     }
    52 
    53     public static void printConstructorMessage(Object obj)
    54     {
    55         Class c = obj.getClass();
    56         System.out.println("类的名称是:" + c.getName());
    57         System.out.println("获取构造函数列表:");
    58         Constructor[] constructors = c.getDeclaredConstructors();
    59         for(Constructor constructor: constructors)
    60         {
    61             System.out.print(constructor.getName() + "(");
    62             Class[] paramTypes = constructor.getParameterTypes();
    63             for(int i = 0; i < paramTypes.length; i++)
    64             {
    65                 String info = paramTypes[i].getName();
    66                 if(i != paramTypes.length - 1)
    67                 {
    68                     info = info + ", ";
    69                 }
    70                 System.out.print(info);
    71             }
    72             System.out.println(")");
    73         }
    74         System.out.println("获取构造函数列表结束。");
    75     }
    76 }

    ClassUtilTest.java:

     1 package com.hxy;
     2 
     3 public class ClassUtilTest 
     4 {
     5     public static void main(String[] args)
     6     {
     7         Integer integer = 6;
     8         ClassUtil.printMethodMessage(integer);
     9         System.out.println("<------------------->");
    10         ClassUtil.printFieldMessage(integer);
    11         System.out.println("<------------------->");
    12         ClassUtil.printConstructorMessage(integer);
    13     }
    14 }

    运行结果:

     1 类的名称是:java.lang.Integer
     2 获取方法列表:
     3 int numberOfLeadingZeros(int)
     4 int numberOfTrailingZeros(int)
     5 int bitCount(int)
     6 boolean equals(java.lang.Object)
     7 java.lang.String toString(int, int)
     8 java.lang.String toString()
     9 java.lang.String toString(int)
    10 int hashCode(int)
    11 int hashCode()
    12 int min(int, int)
    13 int max(int, int)
    14 int reverseBytes(int)
    15 int compareTo(java.lang.Integer)
    16 int compareTo(java.lang.Object)
    17 byte byteValue()
    18 short shortValue()
    19 int intValue()
    20 long longValue()
    21 float floatValue()
    22 double doubleValue()
    23 java.lang.Integer valueOf(java.lang.String, int)
    24 java.lang.Integer valueOf(int)
    25 java.lang.Integer valueOf(java.lang.String)
    26 java.lang.String toHexString(int)
    27 int compare(int, int)
    28 java.lang.Integer decode(java.lang.String)
    29 int reverse(int)
    30 int sum(int, int)
    31 int parseInt(java.lang.String)
    32 int parseInt(java.lang.String, int)
    33 long toUnsignedLong(int)
    34 int compareUnsigned(int, int)
    35 int divideUnsigned(int, int)
    36 java.lang.Integer getInteger(java.lang.String, java.lang.Integer)
    37 java.lang.Integer getInteger(java.lang.String, int)
    38 java.lang.Integer getInteger(java.lang.String)
    39 int highestOneBit(int)
    40 int lowestOneBit(int)
    41 int parseUnsignedInt(java.lang.String)
    42 int parseUnsignedInt(java.lang.String, int)
    43 int remainderUnsigned(int, int)
    44 int rotateLeft(int, int)
    45 int rotateRight(int, int)
    46 int signum(int)
    47 java.lang.String toBinaryString(int)
    48 java.lang.String toOctalString(int)
    49 java.lang.String toUnsignedString(int)
    50 java.lang.String toUnsignedString(int, int)
    51 void wait()
    52 void wait(long, int)
    53 void wait(long)
    54 java.lang.Class getClass()
    55 void notify()
    56 void notifyAll()
    57 获取方法列表结束。
    58 <------------------->
    59 类的名称是:java.lang.Integer
    60 获取成员变量列表:
    61 int MIN_VALUE
    62 int MAX_VALUE
    63 java.lang.Class TYPE
    64 [C digits
    65 [C DigitTens
    66 [C DigitOnes
    67 [I sizeTable
    68 int value
    69 int SIZE
    70 int BYTES
    71 long serialVersionUID
    72 获取成员变量列表结束。
    73 <------------------->
    74 类的名称是:java.lang.Integer
    75 获取构造函数列表:
    76 java.lang.Integer(int)
    77 java.lang.Integer(java.lang.String)
    78 获取构造函数列表结束。

    3.方法的反射

     1 package com.hxy;
     2 import java.lang.reflect.Method;
     3 
     4 class A
     5 {
     6     public void print(int a, int b)
     7     {
     8         System.out.println(a + b);
     9     }
    10 }
    11 
    12 public class MethodReflect 
    13 {
    14     public static void main(String[] args)
    15     {
    16         A obj = new A();
    17         Class c = obj.getClass();
    18         try 
    19         {
    20             //正常方法调用
    21             obj.print(10, 20);
    22             
    23             //方法的反射
    24             Method m = c.getMethod("print", int.class, int.class);
    25             m.invoke(obj, 10, 20);
    26         } 
    27         catch (Exception e) 
    28         {
    29             e.printStackTrace();
    30         } 
    31     }
    32 }

    运行结果:

    1 30
    2 30

    一个简单的例子体现方法反射的优越性:
    UserService.java:

     1 package com.hxy;
     2 
     3 public class UserService 
     4 {
     5     public void delete()
     6     {
     7         System.out.println("Delete Service Starts");
     8     }
     9     
    10     public void update()
    11     {
    12         System.out.println("Update Service Starts");
    13     }
    14     
    15     public void find()
    16     {
    17         System.out.println("Find Service Starts");
    18     }
    19 }

    UserServiceInterface.java:

     1 package com.hxy;
     2 import java.io.BufferedReader;
     3 import java.io.InputStreamReader;
     4 import java.lang.reflect.Method;
     5 
     6 public class UserServiceInterface 
     7 {
     8     public static void main(String[] args) 
     9     {
    10         UserService us = new UserService();
    11         try 
    12         {
    13             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    14             System.out.print("Please Input Your Operation: ");
    15             String action = br.readLine();
    16             /*
    17             常规写法(不符合开闭原则)
    18             if("update".equals(action))
    19             {
    20                 us.update();
    21             }
    22             if("delete".equals(action))
    23             {
    24                 us.delete();
    25             }
    26             if("find".equals(action))
    27             {
    28                 us.find();
    29             }
    30             */
    31             //运用反射的优雅写法
    32             Class c = us.getClass();
    33             Method m = c.getMethod(action);
    34             m.invoke(us);
    35         } 
    36         catch (Exception e) 
    37         {
    38             System.out.println("No Such Service!");
    39         }
    40     }
    41 }

    *:Hibernate等持久层框架中的万能DAO层实现就是基于方法的反射。

    4.从反射理解泛型

     1 package com.hxy;
     2 import java.lang.reflect.Method;
     3 import java.util.ArrayList;
     4 
     5 public class GenericReflect 
     6 {
     7     public static void main(String[] args)
     8     {
     9         ArrayList<String> list1 = new ArrayList<String>();
    10         ArrayList<Integer> list2 = new ArrayList<Integer>();
    11         Class c1 = list1.getClass();
    12         Class c2 = list2.getClass();
    13         System.out.println(c1 == c2);
    14         //true
    15         
    16         //结论:
    17         //反射的操作实际上是编译之后的操作
    18         //.class
    19         //集合泛型,是用来防止错误输入的,只在编译阶段有效
    20         
    21         //验证:
    22         try
    23         {
    24             System.out.println(list1.size());
    25             //0
    26             Method m = c1.getMethod("add", Object.class);
    27             //add一个数字而不是string
    28             m.invoke(list1, 666);
    29             System.out.println(list1.size());
    30             //1
    31             //所以说:反射的操作实际上是编译之后的操作,不受编译阶段检查
    32             //且泛型只在编译阶段有效
    33         }
    34         catch(Exception e)
    35         {
    36             e.printStackTrace();
    37         }
    38     }
    39 }
  • 相关阅读:
    第一课:人人站安装与使用教程
    linux 多个python版本的切换
    参考文章
    windows下scrapy 的安装
    vi 使用入门
    linux 源码安装
    C语言—第二次作业
    C语言第0次作业
    c语言博客园作业03函数
    tomcat对于web.xml的securityconstraint使用的处理机制
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/5735503.html
Copyright © 2020-2023  润新知