java-反射

来源:互联网 发布:python爬虫能做什么 编辑:程序博客网 时间:2024/06/05 05:52


1,构造方法的反射

package javaBase.reflect;import java.lang.reflect.Constructor;/* * 三种获取字节码对应的实例对象(Class类型)的方法: * 九种预定义的 Class 对象,表示八个基本类型和 void * boolean、byte、char、short、int、long、float、 double。  * 源程序中出现的类型,都有各自的Class实例对象:int[] ,void  ..... */public class Test1 {public static void main(String[] args) throws Exception{String str1 = "haha";Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("java.lang.String");//详细System.out.println(cls1 == cls2);//trueSystem.out.println(cls1 == cls3);//true//判断一个类是不是基本数据类型:System.out.println(cls1.isPrimitive());//falseSystem.out.println(int.class.isPrimitive());//trueSystem.out.println(int.class==Integer.class);//Integer是包装类,falseSystem.out.println(int.class == Integer.TYPE);//type:包装的源数据类型  trueSystem.out.println(int[].class.isPrimitive());//数组也是一个类型,不是原始类型System.out.println(int[].class.isArray());//Constructor类代表某个类中的一个构造方法Constructor c1 = String.class.getConstructor(StringBuffer.class);//用反射实现:String s1  = new String(new StringBuffer("abc"));String str2 = (String)c1.newInstance(new StringBuffer("abc"));//编译时:不会执行等号赋值,只检查语法,看定义,所以不知道c1是个什么对象的构造方法System.out.println(str2.charAt(2));}//反射就是将java类中的各种成分映射成相应的java类}

2,成员变量的反射

package javaBase.reflect;//反射就是将java类中的各种成分映射成相应的java类import java.lang.reflect.Constructor;import java.lang.reflect.Field;/* * 三种获取字节码对应的实例对象(Class类型)的方法: * 九种预定义的 Class 对象,表示八个基本类型和 void * boolean、byte、char、short、int、long、float、 double。  * 源程序中出现的类型,都有各自的Class实例对象:int[] ,void  ..... */public class Test1 {public static void main(String[] args) throws Exception{String str1 = "haha";Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("java.lang.String");//详细System.out.println(cls1 == cls2);//trueSystem.out.println(cls1 == cls3);//true//判断一个类是不是基本数据类型:System.out.println(cls1.isPrimitive());//falseSystem.out.println(int.class.isPrimitive());//trueSystem.out.println(int.class==Integer.class);//Integer是包装类,falseSystem.out.println(int.class == Integer.TYPE);//type:包装的源数据类型  trueSystem.out.println(int[].class.isPrimitive());//数组也是一个类型,不是原始类型System.out.println(int[].class.isArray());//Constructor类代表某个类中的一个构造方法Constructor c1 = String.class.getConstructor(StringBuffer.class);//用反射实现:String s1  = new String(new StringBuffer("abc"));String str2 = (String)c1.newInstance(new StringBuffer("abc"));//编译时:不会执行等号赋值,只检查语法,看定义,所以不知道c1是个什么对象的构造方法System.out.println(str2.charAt(2));Point p = new Point(3, 5);//fieldY是类的,不是具体对象的。用它去取某个具体对象上对应的值Field fieldY = p.getClass().getField("y");//y是类的字段名System.out.println(fieldY.get(p));//Field fieldX = p.getClass().getField("x");//找不到,x是privateField  fieldX = p.getClass().getDeclaredField("x");//可以看见了,但是不能取fieldX.setAccessible(true);//暴力反射System.out.println(fieldX.get(p));changeStringValue(p);System.out.println(p);}/* * 将一个对象中的String类型成员变量的值中“b”改成“a” */private static void changeStringValue(Point p) throws Exception {Field[] fields = p.getClass().getFields();for(Field f:fields){if(f.getType()==String.class){//字节码只有一份,用==比较,而不用equals()String oldValue = (String)f.get(p);//获取成员变量值String newValue = oldValue.replace("b", "a");f.set(p, newValue);//成员变量重新赋值}}}}

附:Point类

package javaBase.reflect;public class Point {private int x;public int y;public String str1 = "ball";public String str2 = "bascketball";public String str3 = "it";public Point(int x, int y) {super();this.x = x;this.y = y;}@Overridepublic String toString() {return str1+": "+str2+": "+ str3;}}

3成员方法的反射

//Method 例子:charAt()Method mCharAt = String.class.getMethod("charAt", int.class);char ch = (Character)mCharAt.invoke(str1, 1);//invoke调用.str1这里为null是静态方法System.out.println(ch);

 4,main()方法反射

<span style="white-space:pre"></span>new DoMain().main(new String[]{"111","222","333"});//main()方法,不知道类的名字,只知道到时候传过来要调用其main方法String someClassName = args[0];//传入类名(带包)Method mainMethod = Class.forName(someClassName).getMethod("main", String[].class);mainMethod.invoke(null, (Object)new String[]{"111","222","333"});//静态方法用null/* * jdk1.4把数组当成n个参数,jdk1.5把数组当做一个参数,为了兼容1.4: * java5会自动把数组弄成多个单独参数 * 这两种方法都可以避免数组被拆成几个参数 */mainMethod.invoke(null, new Object []{new String[]{"111","222","333"}});

5,数组的反射

package javaBase.reflect;import java.lang.reflect.Array;/* * 数组的反射 */public class ArrayReflect {public static void main(String[] args) {int[] a1 = new int[3];int[] a2 = new int[4];int[][] a3 = new int[2][3];String[] s = new String[3];System.out.println(int.class.getSuperclass());//null,基本类型没有父类?System.out.println(a1.getClass()==a2.getClass());//true维度,类型相同//System.out.println(a1.getClass() == a3.getClass());//System.out.println(a1.getClass() == s.getClass());System.out.println(a1.getClass().getName());//类名:[ISystem.out.println(a1.getClass().getSuperclass().getName());//objSystem.out.println(a3.getClass().getName());//[[ISystem.out.println(s.getClass().getSuperclass().getName());//objObject o1 = a1;Object o2 = a3;Object o3 = s;//Object[] o4 = a1;//基本数据类型数组不是Object[];整个数组是一个Object对象Object[] o5 = s;Object[] o6 = a3;//降低了维度String[] strings = new String[]{"a","b","c"};printObj(strings);printObj("haha");}/* * 数组的反射类:Array */private static void printObj(Object obj) {Class clazz = obj.getClass();if(clazz.isArray()){int len = Array.getLength(obj);//得到数组长度for(int i=0;i<len;i++){System.out.println(Array.get(obj, i));}}else{System.out.println(obj);}}}

6,反射与框架,通过配置文件创建对象

package javaBase.reflect;import java.io.FileInputStream;import java.io.InputStream;import java.util.*;/* * 当一个对象存储到hashset中后,就不要修改那些参与计算哈希值的字段了 * 否则修改后的对象hashcode值与存入时不同,导致不能找到这个对象和单独删除该对象导致内存泄露 */public class ReflectTest {public static void main(String[] args) throws Exception {InputStream in = new FileInputStream("config.properties");Properties prop = new Properties();prop.load(in);in.close();//关闭资源:当前操作系统的窗口或者什么为其提供资源的对象//用反射建立集合String className = prop.getProperty("className");Collection c = (Collection)Class.forName(className).newInstance();//Collection c = new HashSet();Point p1 = new Point(3, 3);Point p2 = new Point(5, 5);Point p3 = new Point(3, 3);c.add(p1);c.add(p2);c.add(p3);c.add(p1);//p1.y = 7;c.remove(p1);//上面这句执行后会导致remove()找不到p1,从而不能删除System.out.println(c.size());}}


0 0
原创粉丝点击