zoukankan      html  css  js  c++  java
  • javaweb学习总结四(反射技术)

    一:反射的概念

    反射就是加载类,然后获取类的属性、方法、构造函数等。

    二:加载类到内存(有硬盘字节码文件到内存)

    三种加载类的方式:

     1 @Test
     2     // 测试加载类
     3     public void test1() throws Exception {
     4         // 第一种方式
     5         Class clazz1 = Class.forName("com.hlcui.test.Person");
     6         // 第二种方式
     7         Class clazz2 = new Person().getClass();
     8         // 第三种方式
     9         Class clazz3 = Person.class;
    10     }

    三:反射类中的组成部分

    1:使用getConstructor()、getMethod()、getField(),可以反射public修饰的成员,

    如果需要反射private修饰的成员,需要使用下面的getDeclaredXXX()。

    2:反射构造方法

    Person定义的构造方法:

     1 public Person() {
     2         System.out.println("调用无参构造方法...");
     3     }
     4 
     5     public Person(String name) {
     6         System.out.println(name);
     7     }
     8 
     9     public Person(String name, int age) {
    10         System.out.println(name + ":" + age);
    11     }
    12 
    13     private Person(List<String> list) {
    14         System.out.println(list);
    15     }

    反射构造方法代码:

     1 @Test
     2     // 反射无参构造方法
     3     public void test2() throws Exception {
     4         Class clazz1 = Class.forName("com.hlcui.test.Person");
     5         Constructor c = clazz1.getConstructor(null);
     6         Person p = (Person) c.newInstance(null);
     7         System.out.println(p.name);
     8     }
     9 
    10     @Test
    11     // 反射参数String的构造方法
    12     public void test3() throws Exception {
    13         Class clazz1 = Class.forName("com.hlcui.test.Person");
    14         Constructor c = clazz1.getConstructor(String.class);
    15         Person p = (Person) c.newInstance("Jack");
    16         System.out.println(p.name);
    17     }
    18 
    19     @Test
    20     // 反射参数为String、int的构造方法
    21     public void test4() throws Exception {
    22         Class clazz1 = Class.forName("com.hlcui.test.Person");
    23         Constructor c = clazz1.getConstructor(String.class, int.class);
    24         Person p = (Person) c.newInstance("Jack", 27);
    25         System.out.println(p.name);
    26     }
    27 
    28     @Test
    29     // 反射参数为List的构造方法
    30     public void test5() throws Exception {
    31         Class clazz1 = Class.forName("com.hlcui.test.Person");
    32         Constructor c = clazz1.getDeclaredConstructor(List.class);
    33         c.setAccessible(true);
    34         Person p = (Person) c.newInstance(new ArrayList());
    35         System.out.println(p.name);
    36     }

    其中反射参数为List的构造方法,因为构造方法时private修饰的,所以必须使用getDeclaredConstructor()获取构造方法,

    同时需要设置强制方法setAccessible(true);

    也可以直接使用反射类获取对象,代码如下:

    1 @Test
    2     public void test6() throws Exception {
    3         Class clazz1 = Class.forName("com.hlcui.test.Person");
    4         Person p = (Person) clazz1.newInstance();
    5         System.out.println(p.name);
    6     }

    2:反射方法

    反射方法代码如下:

    Person类中定义的普通方法:

     1 public void abc() {
     2         System.out.println("abc...");
     3     }
     4 
     5     public String abc(String name) {
     6         return name;
     7     }
     8 
     9     public void abc(String name, int[] i) {
    10         System.out.println(name + ":" + i);
    11     }
    12 
    13     public Class[] abc(InputStream in) {
    14         return new Class[] { String.class };
    15     }
    16 
    17     public static void abc(int i) {
    18         System.out.println(i);
    19     }

    反射普通方法:

     1 @Test
     2     // public void abc()
     3     public void test7() throws Exception {
     4         Person p = new Person();
     5         Class clazz1 = Class.forName("com.hlcui.test.Person");
     6         Method m = clazz1.getMethod("abc", null);
     7         m.invoke(p, null);
     8     }
     9 
    10     @Test
    11     // public String abc(String name)
    12     public void test8() throws Exception {
    13         Person p = new Person();
    14         Class clazz1 = Class.forName("com.hlcui.test.Person");
    15         Method m = clazz1.getMethod("abc", String.class);
    16         System.out.println(m.invoke(p, "Tom"));
    17     }
    18 
    19     @Test
    20     // public void abc(String name, int[] i)
    21     public void test9() throws Exception {
    22         Person p = new Person();
    23         Class clazz1 = Class.forName("com.hlcui.test.Person");
    24         Method m = clazz1.getMethod("abc", String.class, int[].class);
    25         m.invoke(p, "Jack", new int[] { 1, 2, 3 });
    26     }
    27 
    28     @Test
    29     // public Class[] abc(InputStream in)
    30     public void test10() throws Exception {
    31         Person p = new Person();
    32         Class clazz1 = Class.forName("com.hlcui.test.Person");
    33         Method m = clazz1.getMethod("abc", InputStream.class);
    34         Class[] cc = (Class[]) m.invoke(p, new FileInputStream("f:/1.txt"));
    35         System.out.println(cc[0]);
    36     }
    37 
    38     @Test
    39     // public static void abc(int i)
    40     public void test11() throws Exception {
    41         Class clazz1 = Class.forName("com.hlcui.test.Person");
    42         Method m = clazz1.getMethod("abc", int.class);
    43         m.invoke(null, 27);
    44     }

     Person定义的main方法:

    1 public static void main(String[] args) {
    2         System.out.println("调用main...");
    3     }

    反射main方法:

    1 @Test
    2     // public static void main(String[] args)
    3     public void test12() throws Exception {
    4         Person p = new Person();
    5         Class clazz1 = Class.forName("com.hlcui.test.Person");
    6         Method m = clazz1.getMethod("main", String[].class);
    7         // m.invoke(p, (Object)new String[]{"1","2","3"});
    8         m.invoke(p, new Object[] { new String[] { "1", "2", "3" } });
    9     }

    这里要注意,由于jdk5兼容了jdk1.4的特性,传入字符串数组时,它会对传入参数进行拆分,

    如:new String[]{"1","2","3"}将被拆分成"1"、"2"、"3",所以直接反射会报参数个数异常,

    有两种处理方法:

    a:在前面加上Object  b:将数组再次放到数组中

    3:反射字段

    Person类中定义字段:

    1 public String name = "Tom";
    2     private int age = 27;
    3     private static double salary = 8000.0;

    反射字段:

     1 @Test
     2     // public String name = "Tom";
     3     public void test13() throws Exception {
     4         Person p = new Person();
     5         Class clazz1 = Class.forName("com.hlcui.test.Person");
     6         Field f = clazz1.getField("name");
     7         f.set(p, "Jack");
     8         Object obj = f.get(p);
     9         Class type = f.getType();
    10         if (type.equals(String.class)) {
    11             String value = (String) obj;
    12             System.out.println(value);
    13         }
    14     }
    15 
    16     @Test
    17     // private int age = 27;
    18     public void test14() throws Exception {
    19         Person p = new Person();
    20         Class clazz1 = Class.forName("com.hlcui.test.Person");
    21         Field f = clazz1.getDeclaredField("age");
    22         f.setAccessible(true);
    23         int i = (Integer) f.get(p);
    24         System.out.println(i);
    25     }
    26 
    27     @Test
    28     // private static double salary = 8000.0;
    29     public void test15() throws Exception {
    30         Person p = new Person();
    31         Class clazz1 = Class.forName("com.hlcui.test.Person");
    32         Field f = clazz1.getDeclaredField("salary");
    33         f.setAccessible(true);
    34         double d = (Double) f.get(p);
    35         System.out.println(d);
    36     }

    反射的知识就总结到这里!

  • 相关阅读:
    webstorm 格式化代码及常用快捷键
    Jetbrains 2018 等系列软件激活破解除去黄色警告框方法(含多个平台)
    HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    为什么macos开机黑屏但是有声音?
    mac 回车键、空格键失灵(非物理原因)解决方法
    在VS代码中使用版本控制
    在Visual Studio代码中使用Flask
    [IOI1999]花店橱窗布置(DP路径记录)
    leetcode:Minimum Path Sum(路线上元素和的最小值)【面试算法题】
    c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
  • 原文地址:https://www.cnblogs.com/warrior4236/p/5709403.html
Copyright © 2011-2022 走看看