前言:本博客内容根据张孝祥java高新技术反射篇整理而出
获取Clss实例对象的三种方式
public class ReflectGetClassThreeWaysTest{
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws ClassNotFoundException {
String str ="abc";
//类.class获取
Class cls1=String.class;
//对象getClass获取
Class cls2=str.getClass();
//Class.forName全类名获取
Class cls3 = Class.forName("java.lang.String");
//三个Class为同一个字节码
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
//扩展
//void也是一种字节码
Class vClass=void.class;
//isPrimitive()是否为基本类型
//String不是,而int是 加上void一共九种基本类型字节码
System.out.println(cls1.isPrimitive());
System.out.println(int.class.isPrimitive());
}
}
输出结果:
true
true
false
true
前两个输出为true说明三种方式获得的是同一个字节码。后面的false和true说明了了String不是字节码的基本类型。
反射就是把java类中的各种成分映射成相应的java类。一个java类用一个Class类的对象表示,一个类的组成成分包括:构造方法,成员变量,方法,包等也用一个个的java类表示。分别为Contructor,Field,Method,Package。这里Package暂不做叙述。
字节码中的构造方法Contructor
ContructorTest
//Contructor代表字节码中的一个构造方法
class ContructorTest{
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//反射获取构造器 String String(StringBuffer a)
Constructor constructor= String.class.getConstructor(StringBuffer.class);
String a = (String) constructor.newInstance(new StringBuffer("abc"));
System.out.println(a);
//获取String的无参构造器
String str = String.class.newInstance();
}
}
输出结果:
abc
相当于调用了:
String a = new String (new StringBuffer("abc"));
System.out.println(a);
字节码中的成员变量Field
FieldTest
//Field代表字节码中的一个成员变量
class FieldTest{
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Person person = new Person("张三三", "男");
Class pcls = Person.class;
Field sexField = pcls.getField("sex");
// 获取私有成员
Field nameField = pcls.getDeclaredField("name");
// 要获取私有成员,则必须执行以下语句
nameField.setAccessible(true);
nameField.get(person);
System.out.println(sexField.get(person));
System.out.println(nameField.get(person));
sexField.set(person, "女");
nameField.set(person, "李思思");
System.out.println(sexField.get(person));
System.out.println(nameField.get(person));
System.out.println(person);
}
}
class Person{
public String name;
public String sex;
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + "]";
}
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
输出结果:
男
张三三
女
李思思
Person [name=李思思, sex=女]
字节码中的方法Method
MethodTest
//Method代表字节码中的一个方法
class MethodTest {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
String aString = "abv";
Class<? extends String> strClass = aString.getClass();
Method method = strClass.getMethod("charAt", int.class);
// 相当于调用了aString.charAt(1);
Character charatStr = (Character) method.invoke(aString, 1);
System.out.println(charatStr);
}
输出结果:
b