在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,本文主要讲述Java的反射机制,更多Java专业知识,广州疯狂java培训为你讲解;
一、分析
比如:Person有什么那?姓名,身高,睡觉行为等;而Class用于描述java的类,那有什么那?类名,所属包名,成员变量,成员方法等;Class类没有构造方法,它对应的是个各类的字节码文件,也就是.class文件,同理就是说,每一个类的字节码,都是Class类的实例对象;Person的字节码是Class类的实例对象;Person.class就表示Person在内存中的字节码Date的字节码同样也是Class类的实例对象;Date.class
一》得到各个字节码对应的实例对象(Class类型)三种方法
1.类名.class;如:System.class;
2.对象.getClass();如:new Date().getClass();前提必须由对象名;
3.Class.forName(“类名”);如;Class.forName(“java.util.Date”);
Class的静态方法forName();指定类的完整名称;
返回字节码文件。
反射用的通常是这种方式:因为写源程序的时候还不知道类的名字;
通常用一个变量表示;
二》有九个预定义的class对象,8个基本数据类型,1个void.class
三》
String s = "abc";
Class cls1 = s.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
//因为内存中只有一份字节码,所以不管用那种方式创建,都相等;
System.out.println(cls1 == cls2);
System.out.println(cls1 == cls3);
二、构造方法的反射应用(Constructor类):getConstructor()
一、.得到某个类的所有构造函数:所有的构造方法会装到一个数组里面;
Constructor[] constructors = Class.forName(“java.lang.String”).getConstructors();
二、getConstructor()得到某一个构造方法,构造方法那么多,得到的具体是哪一个那?
就要根据参数类型,参数类型用class对象表示
Constructor cons1 =
String.class.getConstructor(StringBuffer.class ,int.class);
就是表示得到String类中,参数为StringBuffer和int的构造方法;
三、Constructor类中有一个newInstance()方法,根据构造方法创建实例对象;
String str = (String)cons1.newInstance(new StringBuffer("abc"));
四、上面是利用String有参数的构造函数创建对象,其实Class类给我们提供了一个创建对象的方法newInstance(),但是这个方法只能调用无参数的构造方法,比较方便,
String s=(String)Class.forName(“java.lang.String”).newInstance();
同样也创建了一个String对象;
三、成员变量的反射(Field类)getField()
public class ReflectPoint {
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
ReflectPoint pt1 = new ReflectPoint(3,5);
//利用反射得到成员Y,用Filed类,先得到该类的字节码。
//然后得到字节码中的成员变量。
Field fieldY = pt1.getClass().getField("y");
//fieldY的值是多少那?5,错,fieldY对应的是该类的字节码中变量y
//fieldY不是对象身上的变量,而是类上,
//要用它去取某个对象上的值;
System.out.println(fieldY);
System.out.println(fieldY.get(pt1));
//获取x变量,因为x是私有的,java中定义了专用的方法
//反射获取私有变量getDeclaredField();
Field fieldX = pt1.getClass().getDeclaredField("x");
//前面已经获取,下面设置访问私有变量;
//强制访问,setAccessible(true)不能省略,否则运行失败,不让访问私有变量
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
..应用一下:
//将任意个对象中的所有String类型的成员变量所对应
//的字符串内容的“b”替换“a”;
public static void changeStringValue(Object obj)throws Exception
{
//获取字节码中所有的成员变量
Field[] fields = obj.getClass().getFields();
for(Field field : fields)
{
//遍历是否是String类型变量
//这里应该用==号,而不是equals,因为只有一份String字节码,他们用的都是同一分
if(field.getType() == String.class)
{
String oldValue = (String)field.get(obj);
//将b替换成a
String newValue = oldValue.replace("b", "a");
//把新值set给对象
field.set(obj, newValue);
}
}
}
public class ReflectPoint {
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
@Override
public String toString()
{
return str1+"::"+str2+"::"+str3;
}
}
疯狂Java培训专注软件开发培训,提升学员就业能力,重点提升实践动手能力。没有工作经验的学员,在疯狂java,通过大量全真经典企业级项目进行集中培训,课上讲师讲解和课下项目练习课上课下双管齐下,学员通过数月培训都可获得1-2年的工作经验,进而在同类的求职者中脱颖而出。疯狂Java培训让你体会java编程的快乐,项目开发的兴奋,激情,通过短短几个月的时间,让你在半年的时间内掌握8-10万的代码量,掌握Java核心技术,迅速成为技能型的现代化高端人才,迅速获得高薪就业!