java反射学习-以demo加理伦
来源:互联网 发布:英语 荷兰语知乎 编辑:程序博客网 时间:2024/05/01 13:20
一、首先介绍一下Class类是什么?
1.class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class,类型.getClass(),Class.forName(“类名”)等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。(哈哈,以上均来自百度)
2.class的主要方法
class类的方法还是挺多的。主要是用于得到运行时类的相关信息(可用于反射)。
重要的几个方法:
1, public static Class<?> forName(String className) :natice 方法,动态加载类。非常重要。 如在sql中动态加载驱动程序:class.forName(sqlDriver);2,public T newInstance() :根据对象的class新建一个对象,用于反射。非常重要。 可用在反射中构建对象,调用对象方法: class doubleClass= class.forName("java.lang.Double"); Object objDouble = doubleClass.newInstance(); 如在javaBean中就应用了这个方法,因为java默认要有一个无参构造函数。3, public ClassLoader getClassLoader() :获得类的类加载器Bootstrap ,Extension ,System or user custom ClassLoader(一般为system classloader)。重要。4,public String getName() :获取类或接口的名字。记住enum为类,annotation为接口。重要5,public native Class getSuperclass():获取类的父类,继承了父类则返回父类,否则返回java.lang.Object。返回Object的父类为空-null。一般6,public java.net.URL getResource(String name) :根据字符串获得资源。7,其他类 public boolean isEnum() :判断是否为枚举类型。 public native boolean isArray() :判断是否为数组类型。 public native boolean isPrimitive() :判断是否为基本类型。 public boolean isAnnotation() :判断是否为注解类型。public Package getPackage() :反射中获得package,如java.lang.Object 的package为java.lang。public native int getModifiers() : 反射中获得修饰符,如public static void等 。public Field getField(String name):反射中获得域成员。public Field[] getFields() :获得域数组成员。 public Method[] getMethods() :获得方法。public Method getDeclaredMethod(String name, Class<?>... parameterTypes):加个Declared代表本类,继承,父类均不包括。public Constructor<?>[] getConstructors() :获得所有的构造函数。
案例一,获取Class对象:
/** * 每个java类运行时都在JVM里表现为一个class对象, * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> c1=null; Class<?> c2=null; Class<?> c3=null; try { //通过类路径获取Class c1=Class.forName("com.cdc.console.controller.Test"); } catch (ClassNotFoundException e) { e.printStackTrace(); } //通过对象获取Class c2=new Test().getClass(); //通过类名获取Class c3=Test.class; System.out.println("类名称 "+c1.getName()); System.out.println("类名称 "+c2.getName()); System.out.println("类名称 "+c3.getName()); }}
案例二:通过Class实例化对象 newInstance(),类必须有无参构造函数
/** * 通过Class实例化对象 newInstance(),类必须有无参构造函数,否则会报错 * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); try { SysConfLog c = (SysConfLog) conf.newInstance(); c.setBuName("哈哈"); System.out.println(c.getBuName()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }
案例三:通过Class取得全部的构造函数
/** * 通过Class取得所有构造函数getConstructors(),实例化对象 newInstance() * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); Constructor<?>[] ars = conf.getConstructors(); try { SysConfLog c = (SysConfLog) ars[0].newInstance(); SysConfLog c1 = (SysConfLog) ars[1].newInstance("我是叫hxy"); c.setMenuName("我不是hxy"); System.out.println(c.getMenuName()); System.out.println(c1.getMenuName()); } catch (Exception e) { e.printStackTrace(); } }}
注:以节省页面,以下只写出代码核心部分
案例四:返回一个类实现的接口
//保存所有的接口 Class<?> intes[]=demo.getInterfaces(); for (int i = 0; i < intes.length; i++) { System.out.println("实现的接口 "+intes[i].getName()); }
案例五:返回一个类继承的类
//取得父类 Class<?> temp=demo.getSuperclass(); System.out.println("继承的父类为: "+temp.getName());
案例六:取出构造函数的详细信息
/** * 通过Class取得所有构造函数getConstructors(),取出构造函数的详细信息 * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); Constructor<?>cons[]=conf.getConstructors(); for (int i = 0; i < cons.length; i++) { //获取参数类型集合 Class<?> p[]=cons[i].getParameterTypes(); System.out.print("构造方法: "); //获取修饰符的字节码,就是返回一个以特定字节码(十六进制)表示的整数 int mo=cons[i].getModifiers(); System.out.print(Modifier.toString(mo)+" "); //获取类路径 System.out.print(cons[i].getName()); System.out.print("("); //循环参数列表 for(int j=0;j<p.length;++j){ System.out.print(p[j].getName()+" arg"+i); if(j<p.length-1){ System.out.print(","); } } System.out.println("){}"); } }
案例七:获取所有的方法,获取方法的异常
/** * 通过Class取得所有方法,取出方法的详细信息,有异常,打印异常 * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); //获取所有方法 Method method[]=conf.getMethods(); for(int i=0;i<method.length;++i){ //返回类型 Class<?> returnType=method[i].getReturnType(); //参数类型 Class<?> para[]=method[i].getParameterTypes(); ///获取修饰符的字节码,就是返回一个以特定字节码(十六进制)表示的整数 int temp=method[i].getModifiers(); //通过字节码,获取修饰符 System.out.print(Modifier.toString(temp)+" "); System.out.print(returnType.getName()+" "); System.out.print(method[i].getName()+" "); System.out.print("("); for(int j=0;j<para.length;++j){ System.out.print(para[j].getName()+" "+"arg"+j); if(j<para.length-1){ System.out.print(","); } } //方法的抛出异常 Class<?> exce[]=method[i].getExceptionTypes(); if(exce.length>0){ System.out.print(") throws "); for(int k=0;k<exce.length;++k){ System.out.print(exce[k].getName()+" "); if(k<exce.length-1){ System.out.print(","); } } }else{ System.out.print(")"); } System.out.println(); } }
案例八:通过Class取得所有属性,分为本类和父类
/** * 通过Class取得所有属性,分为本类和父类 * 1.可通过类名.class, * 2.对象.getClass(), * 3.Class.forName("类名") * 等方法获取class对象 * @author hxy * */public class Test { public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); //获取所有方法 System.out.println("===============本类属性========================"); // 取得本类的全部属性 Field[] field = conf.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 = conf.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() + ";"); } }
案例九:调用类的set get 方法:
public static void main(String[] args) { Class<?> conf=SysConfLog.class;// Class<?> conf=new SysConfLog().getClass();// Class<?> conf=Class.forName("com.cdc.entity.sys.SysConfLog"); // 取得本类的全部属性 Object obj=null; try { obj=conf.newInstance(); } catch (Exception e) { e.printStackTrace(); } Field[] field = conf.getDeclaredFields(); //赋值 setter(obj, "clientMark", "clientMark", String.class); setter(obj, "clientIp", "clientIp", String.class); for (int i = 0; i < field.length; i++) { getter(obj, field[i].getName()); } } /** * @param obj * 操作的对象 * @param att * 操作的属性 * */ public static void getter(Object obj, String att) { try { att=att.substring(0,1).toUpperCase()+att.substring(1,att.length()); Method method = obj.getClass().getMethod("get" + att); if(method.invoke(obj)==null){ return; } System.out.println(method.invoke(obj)); } catch (Exception e) { e.printStackTrace(); } } /** * @param obj * 操作的对象 * @param att * 操作的属性 * @param value * 设置的值 * @param type * 参数的属性 * */ public static void setter(Object obj, String att, Object value, Class<?> type) { att=att.substring(0,1).toUpperCase()+att.substring(1,att. length()); try { Method method = obj.getClass().getMethod("set" + att, type); method.invoke(obj, value); } catch (Exception e) { e.printStackTrace(); } }
案例十:通过反射修改数组信息和改变数组长度
/** * 通过反射修改数组信息和改变数组长度 * @author hxy * */public class Test { public static void main(String[] args) { int[] temp={1,2,3,4,5}; Class<?>demo=temp.getClass().getComponentType(); System.out.println("数组类型: "+demo.getName()); System.out.println("数组长度 "+Array.getLength(temp)); System.out.println("数组的第一个元素: "+Array.get(temp, 0)); Array.set(temp, 0, 100); System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0)); temp=(int[]) arrayInc(temp, 7); print(temp); } /** * 修改数组大小 * */ public static Object arrayInc(Object obj,int len){ //返回obj数组类型,如果不是数组则返回Null Class<?>arr=obj.getClass().getComponentType(); Object newArr=Array.newInstance(arr, len); int co=Array.getLength(obj); //复制数组 obj-源数组 ,0-从0开始复制 ,newArr-目标数组 ,0-复制到新数组从0开始,co-复制多少长度 System.arraycopy(obj, 0, newArr, 0, co); return newArr; } /** * 打印 * */ public static void print(Object obj){ Class<?>c=obj.getClass(); if(!c.isArray()){ return; } System.out.println("数组长度为: "+Array.getLength(obj)); for (int i = 0; i < Array.getLength(obj); i++) { System.out.print(Array.get(obj, i)+" "); } }
1 0
- java反射学习-以demo加理伦
- Java 反射机制学习Demo
- java 反射的学习demo
- java 反射 demo
- JAVA反射demo例子
- java 反射demo
- Java反射Demo
- java反射机制demo
- Java反射的DEMO
- Java反射Demo
- java 反射demo
- Java反射机制demo
- java反射Demo详解
- java 反射和暴力反射 两个DEMO
- Java反射之方法反射demo
- java反射机制的Demo
- Java编程之反射-demo
- java反射生成DAO【demo】
- Js对Date对象操作详解
- 【C++数据类型】C++中数组名的二义性
- Git配置用户名、邮件地址访问GitHub
- 数据存储2
- playfair加密算法
- java反射学习-以demo加理伦
- Java常用排序算法/程序员必须掌握的8大排序算法
- swift 阿拉伯数字转为汉字
- ZF_20160921_Topcoder
- 计算器事件
- jvm
- APP的六种loading加载样式,全在这
- 单链表逆序详解
- MySQL多实例