------- android培训、java培训、期待与您交流! ----------
1.反射 :反射是基于类的一些操作
(1)类:java程序中的各个java类属于同一类事物,描绘这些事物类名就是Class,如人-Persion java类-Class。
对比想一下 Persion类代表这人类,他的一个实例对象是“张三”,那java类它的实例对象又是对应什么呢?
1.对应各个类在内存中的字节码,如Persion类对应Persion类的字节码等等。
2.当一个类被加载时这个类会占用一块空间,这个空间存储的内容就是这个类的字节码,不同的类的字节码是不同的,这些字节码占用的空间会被一个个对象占用。
(2)获取字节码的方式 一共三种方式
类.Class 如Persion.Class
对象.Class 如 new Persion().getClass()
Class.forName("类名") 如 Class.forName("java.lang.String")
public class ReflectDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = new String("asf");
Class a = str.getClass();
Class b = String.class;
Class c = null;
try {
c = Class.forName("java.lang.String");
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(a==b);//true
System.out.println(a==c);//true
}
}
(3)类的字节码类型
基本类型:判断类的字节码是否是基本类型调用方法isPrimitive();
如String.class.isPrimitive()//String不是基本类型返回一个值flase
int.class.isPrimitive()//int是基本类型 返回一个值true
包装类型:基本类型与包装类的字节码类型是不相同的
System.out.println(int.class.isPrimitive()==Integer.class.isPrimitive())//返回值false
数组类型:数组也是一个类型 它不是基本类型 调用isPrimitive()方法返回值false,去判断是否是数组类型调用方法isArray()
2,反射的操作
(1)什么事反射?
反射就是把java类中的成分映射成相应的java类,如java类中的各种成分,成员变量,方法,构造方法等等都可以用一个java类
来表示
(2)使用反射
1,构造器反射
获取类的构造方法以String为例
Constructors[] Constructors = Class.forName("java.lang.String").getConstructors();
获取String类中所以的构造方法 存放在数组中,同样也可以获取某个构造方法
Constructors Constructors = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
String str1 = (String) constructor.newInstance(new StringBuffer("asf"));
2,成员变量字段的反射
首先也是获取字段的字节码对象getField(),然后根据字节码对象获取相应字段调用方法get()
如果成员变量是私有的得调用getDeclaredField("x") 成为暴力反射
public class DrawText {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
DrawPoiner dp = new DrawPoiner(3,5);
Field fieldy = dp.getClass().getField("y");
Field fieldx = dp.getClass().getDeclaredField("x");
fieldx.setAccessible(true);
//String xx = (String) fieldx.get(dp);
System.out.println(fieldx.get(dp));
System.out.println(fieldy.get(dp));
利用反射替换某个字符串的一个字节
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
DrawPoiner dp = new DrawPoiner(3,5);
Field[] fields = dp.getClass().getFields();
for(Field ff :fields)
{
if(ff.getType()==String.class)
{
String old = (String) ff.get(dp);
String new1 = old.replace('a', 'b');
ff.set(old, new1);
}
}
3.成员方法的反射(String为例)
//String str1 = "abcdefg";
获取类的字节码对象String.class然后调用getMethod("charAt",String.class)
获取到方法后调用invoke(str1,4);具体代码如下:
public class userAction {
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
//str.charAt(2);
String str1 = "qeweeettt";
Method meth = Class.forName("java.lang.String").getMethod("charAt", int.class);
System.out.println(meth.invoke(str1,6));
}
4,数组反射
(1)相同维数同一个类型的的数组则具有相同的Class实例对象
(2)代表数组的Class实例对象的getSuperClass()返回的是父类Object对应Class
(3)基本类型的一维数组可以当做Object使用,非基本类型的数组既可以当成Object使用也可以当成Object[]使用
(4)判断一个obj是否是数组可以调用isArray();数组可以调用Arrays.asList()处理数组
Array工具用来完成数组反射操作
class ArrayDemo{
public static void main(String[] args)throws Exception {
String [] str = new String[]{"x","y","z"};
int[] in = new int[]{1,2,3};
System.out.println(Arrays.asList(in));
System.out.println(Arrays.asList(str));
Class cla = in.getClass();
if(cla.isArray())
{
int len = Array.getLength(in);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(in, i));
}
}else{
System.out.println(in);
}
}