简单了解反射

编程语言分类
    1. 动态语言  javascript是动态语言 
    2. 静态语言(非动态语言)java
  1. 例如:创建一个对象,是否可以在运行时给对象增加属性和方法,java不具有这种特性,对象创建完成后不能增加属性和方法,但是可以通过反射机制实现动态语言的部分特性
  • java中先有类,然后再有对象,类在创建对象的时候只加载一次(方法区)
  • 反射指的是,在程序运行时分析类的结构的能力
  • 反射中常见的类(接口)
    • Class:代表类对象,它是使用反射的入口,可以通过反射获得当前类的属性,方法,父类和实现的接口等
    • Class是一个类型,它的实例有String.class,Double.class,Dog.class;
    • String 的实例:"hello word"
    • 例如:
    • Dog d=new Dog();//将类的结构加载到java虚拟机,然后在堆里创建类对象,一个类只加载一次
    • Class即是当前类的结构(该类相当于模版),将模版加载到jvm,以后创建类对象都先往jvm中查找是否已存在该类的模版
    • JDK API1.6关于Class的说明:
      • Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注解是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

        Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。 

  • 获得类对象的方法(Class的实例),三种
    1. Class c=String.class;(String的类对象,存储的String类的元数据)
    2. Class c=Class.forName(完整的类名);
    3. Class c=对象.getClass();
    • 例如:
    • Class<?> c=String.class;//获得String的类对象
      Class c1=d.getClass();//获得Dog的类对象
      Class c2=Class.forName("com.oracle.test.Dog");
  • Class常用的方法
    • String   getName();//获得当前类的类名
    • System.out.println(c.getName());
      System.out.println(c1.getName());
      System.out.println(c2.getName());
      输出结果为:
      java.lang.String
      com.oracle.test.Dog
      com.oracle.test.Dog
      
      //结果为当前类的全称,包括包名
    • String   getSimpleName();//只获得当前类的名称,不含包名
    • System.out.println(c.getSimpleName());
      输出结果:
      String
    • Class<?>   getSuperClass();//获得当前类的父类
      System.out.println(d.getClass().getSuperclass());
      结果:
      class com.oracle.test.Animal

    • Class<?>[]   getInterfaces();//获得当前类的实现接口类对象或者接口实现的接口,返回值为Class数组
    • 在进行不同类的比较的时候可以直接使用==判断
    • public static void equals(Object o1,Object o2){
      		if(o1.getClass()==o2.getClass()) {
      			System.out.println("类型相同,都是"+o1.getClass());
      		}else {
      			System.out.println("类型不同一个是"+o1.getClass()+"另一个是"+o2.getClass());
      		}
      	}

  • Field类:

    Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。 (JDK API 1.6)

    • 即Field代表类的属性;例如:private int age;(访问修饰符,数据类型,属性名)
  • 获得Field的方法有四种,都是Class类中的方法
    • Field :getField(String name);获得指定名称的公共属性(反映此Class 对象所表示的类或接口的指定公共成员字段)
    • Field[] :getFields();获得所有公共的属性(所有可访问公共字段。)
    • 测试结果:

    • //注意属性为访问修饰符,包名,属性名,可以通过getName()方法只获得属性名
    • 
             
             
      Student st=new Student(); Dog d=new Dog(); System.out.println(d.getClass().getField("name")); getField(st); public static java.lang.String com.oracle.test.Animal.name Student属性有: public java.lang.String com.oracle.vo.Student.sex public java.lang.String com.oracle.vo.Student.type
    • Field getDeclaredField(String name);获得当前类中定义的某个属性
    • Field[] getDeclaredFields();获得当前类的所有属性(不包括继承的属性)
      • /**
         * 获得当前类的所有属性
         * @param obj
         */
        public static void getDeclaredField(Object obj) {
        	Field[] fd=obj.getClass().getDeclaredFields();//获得当前类的所有属性
        	System.out.println(obj.getClass().getSimpleName()+"属性有:");
        	for (Field f : fd) {
        		System.out.println(f);
        	}
        }

        测试结果
      • getDeclaredField(st);
        System.out.println("=======================");
        getDeclaredField(d);
      • Student属性有:
        private int com.oracle.vo.Student.stuid
        private java.lang.String com.oracle.vo.Student.name
        public java.lang.String com.oracle.vo.Student.sex
        public java.lang.String com.oracle.vo.Student.type
        =======================
        Dog属性有:
        public java.lang.String com.oracle.test.Dog.s
        public java.lang.String com.oracle.test.Dog.w
        

    • Field 的用法
      • String getName();获得属性名称
      • Class getType();获得属性类型
      • int  getModifiers(); 返回此类或接口以整数编码的 Java 语言修饰符
      • Field[] fd=obj.getClass().getFields();//获得所有的公共属性
        System.out.println(obj.getClass().getSimpleName()+"属性有:");
        for (Field f : fd) {
        	System.out.println(f.getModifiers()+"  "+f.getType().getSimpleName()+"  "+f.getName());
        }
        Student属性有:
        1  String  sex
        1  String  type
  • 关于modifiers的说明
    •    /**
           * The {@code int} value representing the {@code public}
           * modifier.
           */
          public static final int PUBLIC           = 0x00000001;
      
          /**
           * The {@code int} value representing the {@code private}
           * modifier.
           */
          public static final int PRIVATE          = 0x00000002;
      
          /**
           * The {@code int} value representing the {@code protected}
           * modifier.
           */
          public static final int PROTECTED        = 0x00000004;
      
          /**
           * The {@code int} value representing the {@code static}
           * modifier.
           */
          public static final int STATIC           = 0x00000008;
      
          /**
           * The {@code int} value representing the {@code final}
           * modifier.
           */
          public static final int FINAL            = 0x00000010;
      
          /**
           * The {@code int} value representing the {@code synchronized}
           * modifier.
           */
          public static final int SYNCHRONIZED     = 0x00000020;
      
          /**
           * The {@code int} value representing the {@code volatile}
           * modifier.
           */
          public static final int VOLATILE         = 0x00000040;
      
          /**
           * The {@code int} value representing the {@code transient}
           * modifier.
           */
          public static final int TRANSIENT        = 0x00000080;
      
          /**
           * The {@code int} value representing the {@code native}
           * modifier.
           */
          public static final int NATIVE           = 0x00000100;
      
          /**
           * The {@code int} value representing the {@code interface}
           * modifier.
           */
          public static final int INTERFACE        = 0x00000200;
      
          /**
           * The {@code int} value representing the {@code abstract}
           * modifier.
           */
          public static final int ABSTRACT         = 0x00000400;
      
          /**
           * The {@code int} value representing the {@code strictfp}
           * modifier.
           */
          public static final int STRICT           = 0x00000800;
      
    • 例如:
    • public class Student {
      	
      	public int stuid;
      	private String name;
      	public static String sex;
      	protected String type;
      	Date bitrh;
      	private static final int M=10;
      
      }
      调用getModifiers()方法得到结果为
    • Student属性有:
      1  int  stuid
      2  String  name
      9  String  sex
      4  String  type
      0  Date  bitrh
      26  int  M

    • 根据JDK源码可知,访问修饰符是采用十六进制存储的整型常量
  • 对应的十进制即为:
    • PUBLIC: 1
      PRIVATE: 2
      PROTECTED: 4
      STATIC: 8
      FINAL: 16
      SYNCHRONIZED: 32
      VOLATILE: 64
      TRANSIENT: 128
      NATIVE: 256
      INTERFACE: 512
      ABSTRACT: 1024
      STRICT: 2048
  • 9=8+1即为public static
  • 26=16+8+2即为private static final
  • 关于Modifier的说明
    • 表示程序元素(如类、方法或字段)上的修饰符。

      并非所有修饰符都适用于所有种类的元素。当两个或多个修饰符出现在某一元素的源代码中时,那么按照惯例(尽管没有要求),它们出现的顺序与上述内容中列出常量的顺序相同。(基本按照从小到大的顺序出现)  

    • 常用的方法

    • Stirng :  toString();返回此修饰符的小写名称。(将getModifiers()方法获得的常量转换成对应的访问修饰符

    • static Modifier valueOf(); 返回带有指定名称的该类型的枚举常量。

    • static Modifier[] values();返回该类的所有的枚举常量

  • 使用反射机制生成sql语句
    • 例如生成插入语句
    • 	public static void save(Object obj) {
      		//得到参数对应的类的所有属性字段
      		Field[] f=obj.getClass().getDeclaredFields();
      		StringBuffer sb1=new StringBuffer();//sql语句的前半部分
      		StringBuffer sb2=new StringBuffer();//sql语句的后半部分
      		sb1.append("insert into ").append(obj.getClass().getSimpleName()+" (");
      		sb2.append(" values(");
      		for(int i=0;i<f.length;i++) {
      			if(i<f.length-1) {
      				sb1.append(f[i].getName()+",");
      				sb2.append("?,");
      			}else {
      				sb1.append(f[i].getName()+")");
      				sb2.append("?)");
      			}
      		}
      		System.out.println(sb1.append(sb2).toString());
      	}

    • 执行结果:
    • insert into Student (stuid,name,sex,type,bitrh,M) values(?,?,?,?,?,?)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值