一、获取Class对象的三种方式
- Object ——> getClass();
- 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
- 通过Class类的静态方法:forName(String className)(常用)
public class Test01 {
public static void main(String[] args) {
try {
Class c1 = Class.forName("reflect.Student");
Student student = new Student();
Class c2 = student.getClass();
Class c3 = Student.class;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student{
private String name;
private String id;
public int age;
@Override
public String toString() {
return "reflect.Student{" +
"name='" + name + '\'' +
", id='" + id + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, String id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public Student() {
}
}
结果是三个hashcode一样,表明Class只有一份。
二、哪些类型可以有Class对象
package reflect;
public class Test02 {
public static void main(String[] args) {
Class c1 = Object.class; //类
Class c2 = Comparable.class; //接口
Class c3 = String[].class; //一维数组
Class c4 = int[][].class; //二维数组
Class c5 = Override.class; //注解
Class c6 = Enum.class; //枚举类型
Class c7 = Integer.class; //基本数据类型
Class c8 = void.class; //空
Class c9 = Class.class; //Class自己
Class c10 = int.class;
Class c11 = Pop.Kl.class;
Class c12 = Pop.Sl.class;
System.out.println("类-->" + c1);
System.out.println("接口-->" + c2);
System.out.println("一维数组-->" + c3);
System.out.println("二维数组-->" + c4);
System.out.println("注解-->" + c5);
System.out.println("枚举类型-->" + c6);
System.out.println("基本数据类型-->" + c7);
System.out.println("空-->" + c8);
System.out.println("Class自己-->" + c9);
System.out.println("Int类型-->" + c10);
System.out.println("普通内部类-->" + c11);
System.out.println("静态内部类-->" + c12);
}
}
class Pop{
class Kl{
}
static class Sl{}
}
三、反射创建对象
package reflect;
import pojo.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test03 {
public static void main(String[] args) {
try {
//获取Class对象
Class c1= Class.forName("pojo.Person");
//获取无参构造
Constructor constructor1 = c1.getConstructor();
//获取有参构造
Constructor constructor2 = c1.getConstructor(String.class,String.class,int.class);
Person p1 = (Person)constructor1.newInstance();
Person p2 = (Person)constructor2.newInstance("张三", "123", 21);
System.out.println(p1);
System.out.println(p2);
//反射获取普通方法
Method setName = c1.getMethod("setName", String.class);
setName.invoke(p2,"李四");
System.out.println(p2);
//反射获取私有方法
Method p_setName = c1.getDeclaredMethod("p_setName", String.class);
//关闭安全检测
p_setName.setAccessible(true);
p_setName.invoke(p2,"王五");
System.out.println(p2);
//反射获取属性
Field id = c1.getDeclaredField("id");
id.setAccessible(true);
id.set(p2,"456");
System.out.println(p2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
修改final属性值
package reflect;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test04 {
public static void main(String[] args) {
try {
Class c1 = Class.forName("reflect.Men");
Constructor constructor = c1.getConstructor();
Men m1 = (Men)constructor.newInstance();
Field[] Fields = c1.getDeclaredFields();
AccessibleObject.setAccessible(Fields,true);
for (Field field : Fields) {
String simpleName = field.getType().getSimpleName();
if("String".equals(simpleName)){
field.set(m1,"李四");
}else if("int".equals(simpleName)){
field.set(m1,77);
}else {
field.set(m1,99);
}
}
// name.set(m1,"李四");
// System.out.println(name.get(m1));
System.out.println(m1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Men{
private final String name="张三";
private final int age=12;
private final Integer id=23;
public Men() {
}
public String toString() {
String a = "name="+name+",age="+ age +",id="+ id;
return a;
}
}
反编译Men.class
class Men {
private final String name = "张三";
private final int age = 12;
private final Integer id = 23;
public Men() {
}
public String toString() {
String a = "name=张三,age=12,id=" + this.id;
return a;
}
}
成员变量在.class字节码文件没有初始化值的时候,就算用final修饰,一样可以被通过反射之后进行修改