zoukankan      html  css  js  c++  java
  • Java中的反射

    *传统方式:
       只能静态的创建java对象
    * 反射的特点:
      实现了java对象的动态创建.(可以在不确定类的时候动态创建)
    * 反射的缺点:
       反射的代码效率低,影响程序性能.
    *开发使用:
       反射和传统结合的方式

      

    1.反射创建类对象
      第一种方式--->创建类对象
        Class clazz=Class.forName(全限定路径名);

        eg

           Class clazz=Class.forName("pojo.Person");

      第二种方式---->调用底层使用反射封装的方法
        Class cla02=类.class;

        eg

          Class clazz=Person.class;
    

      


      第三种方式---->调用底层使用反射封装的方法
        Class cla03=对象.getClass();

        eg

        Class cla03=new Person().getClass();
    

      2.反射调用类的基本信息

        获取类对象的包名---->clazz.getPackage()
        获取类的修饰符----->clazz.getModifiers()
        获取类的名称(全限定)----->clazz.getName()
        获取类的名称(类名)----->clazz.getSimpleName()
        获取类的父类的类对象----->clazz.getSuperclass()

      3.反射获取操作类的属性

      获取类属性
        * getFields() 获取所有的公共字段包括父类 返回Field[]
        * getDeclaredFields() 获取所有声明的字段(不包括父类) 返回Field[]
        * getField("属性名") 获取指定的公共字段包括父类 返回Field
        * getDeclaredField("属性名") 获取指定的声明的字段(不包括父类) 返回Field

      

      操作类属性
        * 操作静态属性
        * 类属性对象.get(null) 返回静态属性的值
        * 类属性对象.set(null,"值") 赋值
        * 操作非静态属性
        * 类属性对象.get(Object obj);
        * 类属性对象.set(Object obj,"值");

    public static void operField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
    		//获取类对象
    		Class cla=Class.forName("com.bjsxt.pojo.Student");
    		//获取反射类属性
    			//获取类及其父类的公共字段
    				Field[] fds = cla.getFields();
    				for(Field f:fds){
    					System.out.println("获取属性名------>"+f.getName());
    					System.out.println("获取修饰符------>"+f.getModifiers());
    					System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
    				}
    				System.out.println("******************************");
    			//获取类声明的所有字段
    				Field[] fds2=cla.getDeclaredFields();
    				for(Field f:fds2){
    					System.out.println("获取属性名----->"+f.getName());
    					System.out.println("获取修饰符------>"+f.getModifiers());
    					System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
    				}
    				System.out.println("******************************");
    			//获取指定的字段
    				Field f=cla.getField("pname");//指定获取类及其父类的公共字段
    				System.out.println(f.getName());
    				Field f2=cla.getDeclaredField("money");//指定获取类的所有字段
    				System.out.println(f2.getName());
    				Field f3=cla.getSuperclass().getDeclaredField("pname");//指定获取父类声明的字段
    				System.out.println(f3.getName());
    			//操作字段值
    				System.out.println("************操作静态字段**********************");
    				//操作静态属性
    				Field fs=cla.getDeclaredField("money");
    				fs.set(null,2000);
    				System.out.println(fs.get(null));
    				System.out.println("************操作非静态字段**********************");
    				//操作非静态属性
    				Field fd=cla.getDeclaredField("sname");
    				Object obj=cla.newInstance();
    				fd.set(obj, "李四");
    				System.out.println(fd.get(obj));	
    				//暴力反射操作私有化属性(了解)
    				Field fd2=cla.getDeclaredField("ssex");
    				fd2.setAccessible(true);//暴力反射,操作私有化属性,不安全
    				Object obj2=cla.newInstance();//获取实例化对象
    				System.out.println(fd2.get(obj2));
    				
    	}
    

      3.反射操作类方法

      操作方法:
        * 获取类对象
        * 获取方法对象
        * getMethods() 获取所有的公共方法包括父类
        * getDeclaredMethods() 获取所有声明的方法不包括父类
        * getMethod(String name,Class...cla) 获取指定的公共方法
        * String name 表示方法名
        * Class...cla 表示方法接收的参数类型的类对象
        * getDeclaredMethod(String name,Class...cla) 获取指定的声明方法
        * String name 表示方法名
        * Class...cla 表示方法接收的参数类型的类对象
      操作方法
        * 静态方法
        * 方法对象.invoke(null,参数值1,参数值2,....);
        * 方法对象.invoke(null,null);
        * 非静态方法
        * Object obj=cla.newInstance();
        * 方法对象.invoke(obj,参数值1,参数值2,....)
        * 方法对象.invoke(obj,null)

    //操作方法
    	private static void operMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
    		//获取类对象
    		Class cla=Class.forName("com.bjsxt.pojo.Student");
    		//获取类方法对象
    			//获取所有的公共方法包括父类
    			Method[] ms=cla.getMethods();
    			for(Method m:ms){
    				System.out.println("获取方法名--->"+m.getName());
    
    			}
    			System.out.println("************************************");
    			//获取所有声明的方法不包括父类
    			Method[] ms2=cla.getDeclaredMethods();
    			for(Method m:ms2){
    				System.out.println("获取方法名--->"+m.getName());
                                    System.out.println("方法的修饰符类型" + m.getModifiers());
                                    System.out.println("方法的返回值类型" + m.getReturnType());
            
    			}
    			//获取指定的公共方法包括父类
    				Method m=cla.getMethod("pHi", int.class,String.class);
    				System.out.println(m.getReturnType());
    			//获取指定的声明的方法,不包括父类
    				Method m2=cla.getDeclaredMethod("sHello",null);
    				System.out.println(m2.getName());
    			//执行方法
    				//静态方法
    					Method m3=cla.getDeclaredMethod("sHi",String.class);
    					m3.invoke(null, "今天学了反射");
    				//非静态
    					Method m4=cla.getDeclaredMethod("sHi",int.class,String.class);
    					m4.invoke(cla.newInstance(), 3,"反射");
    	}                                
    

      4.获取构造器为了创建该类的实例对象

        直接用 cla.newInstance("形参")创建对象

    理解:类是对象的抽象,Class也是类,Class类是对类的一直抽象。

  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/kilig/p/12116219.html
Copyright © 2011-2022 走看看