------- android培训、java培训、期待与您交流! ----------
Class类:
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。
得到各个字节码对应的实例对象的方法:( Class类型):
1、类名.class。
例如,System.class
2、对象.getClass()。
例如,new Date().getClass()
3、Class.forName("类名")。
例如,Class.forName("java.util.Date");
.class和Class.forName的区别:
后者可以在不确定要获得字节码的具体类的时候使用,传入的是一个字符串,经常在框架中使用。
九个预定义类型的实例对象:
基本的 Java 类型(boolean
、byte
、char
、short
、int
、long
、float
和double
)和关键字void
也
表示为Class
对象。基本类型的字节码获取方式只有一种就是类名.class。
String str1 = "abc"; Class cls1 = str1.getClass(); Class cls2 = String.class; Class cls3 = null; try { cls3 = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(cls1 == cls2);//true System.out.println(cls1 == cls3);//true System.out.println(cls2 == cls3);//true System.out.println(int.class == Integer.class);//false System.out.println(int.class == Integer.TYPE);//true
反射:
反射就是把Java类中的各种成分映射成相应的java类。
构造方法的反射:
onstructor类代表某个类中的一个构造方法;
得到某个类所有的构造方法:
例子:
Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
例子:
Constructor constructor=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
获得方法时要用到类型:
创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
调用获得的方法时要用到上面相同类型的实例对象
Class.newInstance()方法:
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。也就是使用String类的无参构造
方法创建了一个String对象。
以下是用参数为StringBuffer类型的构造函数创建一个String类型的实例对象:
Constructor<String> con1 = String.class.getConstructor(StringBuffer.class); String str2 = con1.newInstance(new StringBuffer("abc")); System.out.println(str2.charAt(2));
Field的反射:
Field类代表某个类中的一个成员变量。
ReflectPoint pt1 = new ReflectPoint(3,5); Field fieldY = pt1.getClass().getField("y");//获取公有的成员变量 System.out.println(fieldY.get(pt1)); Field fieldX = pt1.getClass().getDeclaredField("x");//强行获取私有的成员变量 fieldX.setAccessible(true);//可以获取私有成员变量的值 System.out.println(fieldX.get(pt1));
综合示例:
private static void changeStringValue(Object obj) throws Exception { Field[] fields = obj.getClass().getFields();//获取所有公有的成员变量 for(Field field : fields) {//遍历这些成员变量 if(field.getType() == String.class){//判断该变量的类型是不是String String oldValue = (String)field.get(obj); String newValue = oldValue.replace('b', 'a');//替换 field.set(obj, newValue);//设置新值 } } } ReflectPoint类: public class ReflectPoint { private int x; public int y; public String str1 = "ball"; public String str2 = "basketball"; public String str3 = "itcast"; public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } @Override public String toString() { return str1+":"+str2+":"+str3; } }
成员方法的反射(Method):
Method类代表某个类中的一个成员方法。
得到类中的某一个方法:
例子:
Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式: System.out.println(charAt.invoke(str, 1));
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!
Method methodCharAt = String.class.getMethod("charAt", int.class); System.out.println(methodCharAt.invoke(str1, 1));
jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object... args) 可变参数;
Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法,需要将一个数组作为参数
传递给invoke方法,数组中的每个元素分别对应被调用方法中的一个参数。
main方法的调用: String startingClassName = args[0]; Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class); mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
为了兼容1.4版本没有可变参数方法,传入的一个数组对象会被自动拆包,变为多个参数,因此要打包成
一个Object对象传入,避免被拆包。
数组的反射:
1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
3、基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维
数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
int [] a1 = new int[]{1,2,3}; int [] a2 = new int[4]; int[][] a3 = new int[2][3]; String [] a4 = new String[]{"a","b","c"}; System.out.println(a1.getClass() == a2.getClass());//true System.out.println(a1.getClass() == a4.getClass());//false System.out.println(a1.getClass() == a3.getClass());//false System.out.println(a1.getClass().getName()); System.out.println(a1.getClass().getSuperclass().getName()); System.out.println(a4.getClass().getSuperclass().getName());
无法通过反射直接获得数组中元素的类型,但可以通过其中一个元素获得类型:
a[0].getClass().getName();
private static void printObject(Object obj) { Class clazz = obj.getClass();//获取obj的类型字节码 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);//如果不是数组类型,则直接打印 } }
泛型的反射:
通过反射获取方法,再获得方法的参数列表的类型,获取其参数的实际类型。
Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class); Type[] types = applyMethod.getGenericParameterTypes(); ParameterizedType pType = (ParameterizedType) types[0]; System.out.println(pType.getActualTypeArguments()[0]); } public static void applyVector(Vector<Date> v1) { }
相关推荐
黑马程序员_毕向东_Java基础视频教程第18天-14-IO流(拷贝文本文件图例).zip
黑马程序员_Java基础辅导班教程课件[第01期]第15天
黑马程序员_Java基础辅导班教程课件[第01期]第12天
黑马程序员_Java基础辅导班教程课件[第01期]第8天
黑马程序员_Java基础辅导班教程课件[第01期]第12天
黑马程序员_Java基础辅导班教程课件[第01期]第11天
黑马程序员_hibernate框架开发2016版讲义和笔记资料_day02
黑马程序员_Java基础辅导班教程课件[第01期]第7天
黑马程序员_Java基础辅导班教程课件[第01期]第5天
黑马程序员_hibernate框架开发2016版讲义和笔记资料_day1_day2_day3_day4 包含4天的教学文档
黑马程序员_Java基础辅导班教程课件[第01期]第12天
黑马程序员_Java基础辅导班教程课件[第01期]第6天
黑马程序员_Java基础辅导班教程课件[第01期]第4天
黑马程序员_Java基础辅导班教程课件[第01期]第10天
黑马程序员_Java基础辅导班教程课件[第01期]第9天
黑马程序员_张孝祥_Java多线程与并发库,视频+代码+资料
( 01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip )
黑马程序员_张孝祥_Java多线程与并发库,老师讲的非常仔细,老师很有耐心.欢迎大家下载学习.
黑马程序员_毕向东_Java基础视频教程第22天-06-GUI(Action事件).zip
黑马程序员_毕向东_Java基础视频教程第18天-09-IO流(文件的续写)