zoukankan      html  css  js  c++  java
  • 反射

    1.反射

    1.1.反射概述

    一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意方法和属性; 这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

    1.2.优缺点

    1.2.1优点

    a.反射提高了程序的灵活性和扩展性。
    b.降低耦合性,提高自适应能力。
    c.它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

    1.2.2缺点

    a.性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
    b.使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术因而会带来维护的问题,反射代码比相应的直接代码更复杂。

    2.Class介绍

    2.1.获取Class的方式

    (1)如果持有一个对象,可以直接通过Object类中继承的getClass方法获取。

    Student s = new Student();
    Class clazz = s.getClass();
    

    (2)可以直接通过类包(接口)直接调用其属性.class获取

    Class clazz = Student.class
    

    (3)可以通过Class类中提供的forName方法获取

    Class clazz = Class.forName("全类名");
    

    2.2.通过Class对象获取Constructor、Field、Method

    2.2.1通过Class对象获取Constructor

    getConstructor(Class<?>...parameterType)    //它获取的是类的public构造
    getConstructors	//它获取的是类的所有的public构造
    			
    getDeclaredConstructor(Class<?>...parameterType)  //获取的一个类的任意构造方法(私有和非私有的都可以)
    getDeclaredConstructors	//获取的是类的所有的构造(包括私有的)例如:  

    (1)获取非私有的实例化对象的代码

    //获取Student的Class对象
    Class clazz = Class.forName("com.ccsoft.Student");
    //获取构造方法对象
    Constructor ct = clazz.getConstructor();
    //获取Student的实例化对象
    Object obj = ct.newInstance();
    //也可以强转 Student stu = (Student)ct.newInstance();
    			 
    

    (2)获取包括私有的实例化对象的代码

    /获取Student的Class对象
    Class clazz = Class.forName("com.ccsoft.Student");
    //获取构造方法对象
    Constructor ct = clazz.getDeclaredConstructor();
    //取消检查
    ct.setAccessible(true);		
    //获取Student的实例化对象																					 
    Object obj = ct.newInstance();
    //也可以强转 
    Student stu = (Student)ct.newInstance();
    

    2.3 Field介绍

    getField(String name)  //获取一个Field对象(非私有的),
    getFields()	  //获取包含所有的Field对象的数组(非私有的),	
    getDeclaredField(String name) //获取任意一个Field对象(包含私有的和非私有的),
    getDeclaredFields()  	//获取包含所有的Field对象的数组(包含私有的和非私有的), 

    举例:给Student类的私有age赋值

    //获取Student的Class对象
    Class clazz = Class.forName("com.itheima01.Student");
    //获取属性对象
    Field field_age = clazz.getDeclaredField("age");
    //取消检查
    field_age.setAccessible(true);
    //赋值操作
    field_age.set(Student,18);
    

    2.4 Method介绍

    getMethod(String name,Class<?>...parameterType)	//获取本类中非私有方法的对象
    getMethods()	//获取本类和父类以及超类的非私有方法的对象的数组
    getDeclaredMethod(String name,Class<?>...parameterType)	//获取本类中任意方法的对象
    getDeclaredMethods()	//获取本类包含私有的方法对象的数组
    

    invoke方法:Method对象.invoke(类的实例化对象,方法参数)

    User user  = new User();
    
    // 1.获取sayHello方法
    
    // 1.获取sayHello方法的Method对象
    Class clazz = user.getClass();
    
    // 2.获取Method对象	|->此处传递的class是方法中的参数.class
    Method method = clazz.getMethod("sayHello", String.class);
    
    // 3.让方法执行
    Object invoke = method.invoke(user, "fox");
    
    System.out.println(invoke);
    

    2.5.Method的invoke使用时注意事项

    2.5.1如果方法是static,我们怎样调用?

    如果方法是静态的,在通过invoke调用时不需要传递对象

    Method method = clazz.getMethod("sum");
    method.invoke(null);
    

    2.5.1 如果方法的参数是一个数组类型,怎样处理?

    (1)将args直接强制转换成Object再传递。

    Integer[] args = {1,2,3,4};
    
    method.invoke(user,(object)args);
    

    (2)在数组参数的外面再包装一层数组

    Object[] obj={args};
    
    mothod.invoke(user,obj); 
    

    3.反射案例

    将Map集合中的数据匹配javaben 中的属性,并将值赋给javabean中的属性。

     

     1 @Test
     2                 public void test() {
     3 
     4                     Map<String, Object> map = new HashMap<String, Object>();
     5                     map.put("username", "tom");
     6                     map.put("age", 20);
     7                     map.put("sex", "男");
     8                     map.put("address", "北京");
     9 
    10                 }
    11 
    12                 // 通过属性对应setXxx方法来完成操作
    13                 @Test
    14                 public void test2() throws Exception{
    15                     Map<String, Object> map = new HashMap<String, Object>();
    16                     map.put("username", "tom");
    17                     map.put("age", 20);
    18                     map.put("sex", "男");
    19                     map.put("address", "北京");
    20                     // 1.得到Person类的Class
    21                     Class clazz = Class.forName("com.itheima.reflect.Person");
    22                     Object obj = clazz.newInstance();
    23                     //2.得到Person类中的方法
    24                     Method[] methods = clazz.getDeclaredMethods();
    25                     //3.遍历map
    26                     for(String key:map.keySet()){
    27                         //将所有的key前面添加上set,与方法的名称不区分大小写来对比。
    28                         String methodName="set"+key; //操作的方法
    29                         for(Method method:methods){
    30                             String mname=method.getName();
    31                             if(methodName.equalsIgnoreCase(mname)){
    32                                 method.invoke(obj, map.get(key));
    33                             }
    34                         }
    35                     }
    36                     System.out.println(obj);
    37                 }
    38                 // 通过属性来完成操作
    39                 @Test
    40                 public void test1() throws Exception {
    41                     Map<String, Object> map = new HashMap<String, Object>();
    42                     map.put("username", "tom");
    43                     map.put("age", 20);
    44                     map.put("sex", "男");
    45                     map.put("address", "北京");
    46                     // 1.得到Person类的Class
    47                     Class clazz = Class.forName("com.itheima.reflect.Person");
    48                     Object obj = clazz.newInstance();
    49                     // 2.得到Person类的所有属性
    50                     Field[] fds = clazz.getDeclaredFields();
    51                     // 3.得到map中所有的key
    52                     Set<String> keys = map.keySet();
    53                     for (Field f : fds) {
    54                         String field_name = (f.getName()); // 得到属性名称
    55 
    56                         if (keys.contains(field_name)) { // map的key中包含了Person类的属性
    57                             // 4.将key对应的value赋值给属性
    58                             f.setAccessible(true);
    59                             f.set(obj, map.get(field_name));
    60                         }
    61                     }
    62                     System.out.println(obj);
    63                 }

     

      

  • 相关阅读:
    Kubernetes(k8s)中namespace的作用、反向代理访问k8s中的应用、k8s监控服务heapster
    Kubernetes(k8s)中dashboard的部署。
    Kubernetes(k8s)中Pod资源的健康检查
    Kubernetes(k8s)安装dns附件组件以及使用
    Kubernetes(k8s)的deployment资源
    Kubernetes(k8s)的Service资源
    Kubernetes(k8s)的RC(Replication Controller)副本控制器
    Kubernetes(k8s)常用资源的使用、Pod的常用操作
    简易图书管理系统(主要是jsp+servlet的练习),基于jsp+servlet的图书管理系统
    js 提取 sql 条件 表名 limit
  • 原文地址:https://www.cnblogs.com/battlecry/p/9911286.html
Copyright © 2011-2022 走看看