java进阶(三):反射(1)——构造方法和属性的反射
来源:互联网 发布:大数据技术之企业发展 编辑:程序博客网 时间:2024/06/05 00:24
一、构造方法的反射——Constructor
先附上ChinaPerson接口和Person类
package com.reflect.net;public interface ChinaPerson {public static final String name = "邵小宝";public static int age = 26;public void sayChina();public void sayHello(String name, int age);}
package com.reflect.net;/** * * Person.java * * @title * @description * @author SAM-SHO * @Date 2014-8-28 */public class Person implements ChinaPerson{private String name;private int age;private String sex;public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Person() {}public Person(String name) {this.name = name;}public Person(int age) {this.age = age;}public Person(String name, int age) {this.age = age;this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "[" + this.name + " " + this.age + "]";}@Overridepublic void sayChina() {System.out.println("hello ,china,邵小宝");}@Overridepublic void sayHello(String name, int age) {System.out.println(name+" "+age);}}
1、得到所有的构造方法:getConstructors()
2、得到单个构造方法:getConstructor()或者getConstructor(Object.class)
public static void main(String[] args) throws Exception { Class<?> demo=null; try{ demo=Class.forName("com.reflect.net.Person"); }catch (Exception e) { e.printStackTrace(); } //取得父类 Class<?> temp = demo.getSuperclass(); System.out.println("继承的父类为: "+temp.getName()); //取得构造方法 Constructor<?>cons[] = demo.getConstructors(); for (int i = 0; i < cons.length; i++) { System.out.println("构造方法: "+cons[i]); } //取得单个构造方法,调用的是Person无参的构造方法 Constructor<?> con = demo.getConstructor(); System.out.println("单个无参构造方法: "+con); //取得单个有参构造方法 Constructor<?> con2 = demo.getConstructor(String.class); System.out.println("单个有参构造方法: "+con2); //取得单个有参构造方法 Constructor<?> con3 = demo.getConstructor(String.class,int.class); System.out.println("单个有参构造方法: "+con3); }
3、通过构造方法创建对象
public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("com.reflect.net.Person"); }catch (Exception e) { e.printStackTrace(); } Person per1=null; Person per2=null; Person per3=null; Person per4=null; //取得全部的构造函数 Constructor<?> cons[]=demo.getConstructors(); try{ //顺序乱的,有可能报错 per1=(Person)cons[0].newInstance("邵小宝"); per2=(Person)cons[1].newInstance(20); per3=(Person)cons[2].newInstance("邵小宝",20); per4=(Person)cons[3].newInstance(); //利用无参的构造方法,创建对象:Person person1 = new Person(); Constructor<?> con1 =demo.getConstructor(); Person person1 = (Person) con1.newInstance(); System.out.println(person1); //通过有参的构造函数,创建对象:Person person1 = new Person("SAM-SHO",28); Constructor<?> con2 =demo.getConstructor(String.class,int.class); Person person2 = (Person) con2.newInstance("SAM-SHO",28); System.out.println(person2); }catch(Exception e){ e.printStackTrace(); } System.out.println(per1); System.out.println(per2); System.out.println(per3); System.out.println(per4); }
//【运行结果】:/*[邵小宝 0] [null 20] [邵小宝 20] [null 0] [null 0] [SAM-SHO 28] */
public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("com.reflect.net.Person"); }catch (Exception e) { e.printStackTrace(); } Person per=null; try { //直接调用无参的构造方法,默认会先调用默认的构造方法 per=(Person)demo.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } per.setName("邵小宝"); per.setAge(20); System.out.println(per); }
【运行结果】:[邵小宝 20]但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:比如我定义了一个构造函数:public Person(String name, int age) { this.age=age; this.name=name; }然后继续运行上面的程序,会出现:java.lang.InstantiationException: com.reflect.Person<span style="white-space:pre"></span>at java.lang.Class.newInstance0(Class.java:340)<span style="white-space:pre"></span>at java.lang.Class.newInstance(Class.java:308)<span style="white-space:pre"></span>at com.reflect.Hello3.main(Hello3.java:21)Exception in thread "main" java.lang.NullPointerException<span style="white-space:pre"></span>at com.reflect.Hello3.main(Hello3.java:29)所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数
二、成员变量的反射——Field
1、得到属性方法:getField(Striing str)和getFields(),但是不能得到私有属性,这时需要方法getDeclaredFields()和getDeclaredField(Striing str)
2、得到属性的类型:getType();类型的比较直接用“==”,不需要用equals。如field.getType() == String.class;
3、设置属性的值:set(Object obj, Object value);得到属性的值get(Object obj)。注意:设置和取值需要去操作某个对象。
public static void main(String[] args) throws Exception { Class<?> demo = null; try { demo = Class.forName("com.reflect.net.Person"); } catch (Exception e) { e.printStackTrace(); } System.out.println("===============本类属性========================"); // 取得本类的全部属性 Field[] field = demo.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 权限修饰符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("===============实现的接口或者父类的属性========================"); // 取得实现的接口或者父类的属性 Field[] filed1 = demo.getFields(); for (int j = 0; j < filed1.length; j++) { // 权限修饰符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } //2-得到单个的属性:如得到name属性 Class<?> clazz = Class.forName("com.reflect.net.Person");//new 一个对象 Person person = (Person) clazz.newInstance(); Field name = clazz.getField("name");//得到Pserson实例的name的属性 Class<?> nameType = name.getType(); System.out.println("属性的类型 " + nameType); name.set(person, "sam-sho");//设置属性的值 String value = (String) name.get(person);//需要去具体取某个对象上的值,get(person)方法 System.out.println("属性的值:" + value); //3-得到私有属性:如果把Person的age属性设为private// Field name = clazz.getField("age");//报错:Exception in thread "main" java.lang.NoSuchFieldException: age Field dName = clazz.getDeclaredField("age"); dName.setAccessible(true);// 对私有属性的的暴力反射 dName.set(person, 99); int ageValue = (Integer)dName.get(person);System.out.println("私有属性的值" + ageValue);//综合使用:修改某个对象所有String成员变量的值changstringValue(person,'s','S');//sam-sho, s变成大写System.out.println(person); }/** * 修改某个对象所有String成员变量的值:有"b",改成""; */private static void changstringValue(Object object,char a, char b) throws IllegalArgumentException, IllegalAccessException {Field[] arrField = object.getClass().getFields();for (Field field : arrField) {System.out.println(field.getType());//得到类型System.out.println(field.getName());// 因为是同一份字节码,用"==",而不需要equalsif(field.getType() == String.class) {String oldValue = (String) field.get(object);//得到旧的值String newValue = oldValue.replace(a,b);field.set(object, newValue);//设置新的值}}}
【输出】===============本类属性========================public java.lang.String name;private int age;private java.lang.String sex;===============实现的接口或者父类的属性========================public java.lang.String name;属性的类型 class java.lang.String属性的值:sam-sho私有属性的值99class java.lang.Stringname[Sam-Sho 99]
4、利用属性的反射,就可以写类似于BeanUtils的copyProperties()方法。
/** * 把对象b的值赋给对象a * * @return Object */public Object transFields(Object a, Object b) {Class c1 = a.getClass();Class c2 = b.getClass();Field[] fieldsDest = c1.getDeclaredFields();Field[] fieldsOrg = c2.getDeclaredFields();AccessibleObject.setAccessible(fieldsDest, true);AccessibleObject.setAccessible(fieldsOrg, true);// logger.debug("----fieldDest.length:"+fieldsDest.length);for (int i = 0; i < fieldsDest.length; i++) {Field f = fieldsDest[i];Class type = f.getType();String name = f.getName();String typeName = type.getName();// logger.debug("[Time]::"+i+"[colname]:"+name+"[Typename]:"+typeName);if (name.equals("FIELDNUM") || name.equals("PK")|| name.equals("mErrors") || name.equals("fDate")) {continue;}for (int j = 0; j < fieldsOrg.length; j++) {// 得到数据源的数据Field f1 = fieldsOrg[j];// Class type1 = f1.getType();String name1 = f1.getName();String typeName1 = type.getName();// logger.debug("[times]:"+j+"[colname1]:"+name1+"[Typename1]:"+typeName1);// 取出冗余变量if (name.equals("FIELDNUM") || name.equals("PK")|| name.equals("mErrors") || name.equals("fDate")) {continue;}// 赋值转换if ((typeName.equals(typeName1)) && (name1.equals(name))) {switch (transType(typeName)) {case 3:try {f.setDouble(a, f1.getDouble(b));} catch (Exception e) {e.printStackTrace();}break;case 5:try {f.setInt(a, f1.getInt(b));} catch (Exception e) {e.printStackTrace();}break;case 93:try {f.set(a, f1.get(b));} catch (Exception e) {e.printStackTrace();}break;default:try {f.set(a, f1.get(b));// logger.debug("------Default:"+f1.get(b));} catch (Exception e) {e.printStackTrace();}break;}}}}return a;}
0 0
- java进阶(三):反射(1)——构造方法和属性的反射
- java 反射(三) 打印Class的构造、属性、方法
- java进阶(三):反射(2)——Mothed,方法的反射
- java再复习——通过反射使用类的属性,方法和构造器
- Java反射机制——获取Class对象,属性和方法(三)
- JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践
- 反射(1)——构造方法
- 反射(构造方法Constructor的反射)
- Java反射三 构造方法
- Java反射三 构造方法
- Java反射机制(三):调用对象的私有属性和方法
- java 反射(四) 反射对属性、方法的操作
- java进阶(三):反射(3)——数组的反射与集合的运用(ArrayList、HashSet)
- Java 反射学习(三)成员方法的反射
- Java反射学习总结二(用反射调用对象的私有属性和方法)
- java 反射(二) 反射中Class常见的方法和属性
- Java反射-------构造方法的反射应用
- Java进阶(极客)——反射机制(三)Method 对象的机制与实现
- poj 1088 滑雪(动态规划:记忆化搜索)
- Objective-C语法之NSArray和NSMutableArray
- SQL总结(一)
- Fedora16 Kernel 编译
- #define总结-#define用法集锦
- java进阶(三):反射(1)——构造方法和属性的反射
- CentOS上编译安装OpenCV-2.3.1与ffmpeg-2.1.2
- Oracle 11g R2 for Win7旗舰版(64位)的安装步骤
- JavaSe基础XX17——常用对象API-集合框架_1
- linux常用命令
- 保时捷贴膜后与出租撞衫 被误当为土豪出租车
- OpenCV基础篇之读取显示图片
- 【2014】【辛星】【php】【序言】2014年辛星PHP教程秋季班重磅来袭,期待您的关注
- Android悬浮窗口