1、class的基本介绍
得到class字节码的三种方式:
Person p1 = new Person();
Person p2 = new Person();
第一种:
Person.class
第二种:
p1.getClass();
第三种:forName的作用返回字节码,这份字节码加载过,待着虚拟机过,直接去加载,另一种没有加载过字节码,用类加载器去加载,把加载来的字节码放到虚拟机中,以后不用再加载。
Class.forName("java.lang.string");
有9个预定义对象,基本的 Java 类型(boolean
、byte
、char
、short
、int
、long
、float
和double
)和关键字
void
也表示为 Class
对象。
String str1="abc";
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls2==cls3);
注意:都是同一个字节码,在虚拟机里只有一份字节码
2、反射就是把java类中的各种成分映射成相的java类
构造函数的反射 例子:
//new String(new StringBuffer("abc"));
Class string=String.class;
Constructor<String> con=string.getConstructor(StringBuffer.class);
String str=con.newInstance(new StringBuffer("abc"));
System.out.println(str);
成员变量反射 例子:
ReflectPoint reflectPoint = new ReflectPoint(3, 5);
Field field=reflectPoint.getClass().getField("y");
//field的值不是对象身上的变量而是类上的,要用它去取某个对象的值
System.out.println(field.get(reflectPoint));
//如果是私有的对象用这个方法就能显示出来
Field fieldx=reflectPoint.getClass().getDeclaredField("x");
fieldx.setAccessible(true);
System.out.println(fieldx.get(reflectPoint));
题目:改变成员值内容用‘a’替代‘b’
private static void changStringValue(final Object object){
Field[] fields = object.getClass().getFields();
for(Field field : fields){
//字节码只有一份用 == 比较
if(field.getType() == String.class){
try {
String oldValue = (String) field.get(object);
String newValue = oldValue.replace('b', 'a');
field.set(object, newValue);
System.out.println(field.get(object));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
3、成员方法的反射
//调用String.charAt(1)方法
Method method=String.class.getMethod("charAt", int.class);
//对象和参数
System.out.println(method.invoke(str1,1));
//调用静态方法,静态方法不需要对象
method.invoke(null,1);