把Java类中的各种成分映射成单独的Java对象进行操作。
换言之,如果类是小白鼠的话,反射就是对其一系列的解剖操作。
类中的成分包括:类和类的成员信息、类的构造方法、类的方法、类的属性。
对于类中的这些成分,有专门的类用于获取:
Class
类:可获取类和类的成员信息。
Field
类:可访问类的属性。
Method
类:可调用类的方法。
Constructor
类:可调用类的构造方法。
反射的操作步骤有以下这些:
Class
类是 类的类型 ,每一个类都是Class类的实例,每个类只有一个Class实例(类对象
)。
Class类是反射中专门用于获取 类和类的成员信息 的类。
需要处理异常:ClassNotFoundException
类对象的创建共有三种方式:
Student zhangsan = new Student();
Class<?> class1 = zhangsan.getClass();
class
属性获取。(此方法耦合性高,不推荐)Class<?> class2 = Student.class;
Class.forName()
获取。(此方法耦合性低,推荐!)Class<?> class3 = Class.forName("Student");
作用:获取类的全名称(包含包名)
返回值类型:String
代码演示:
Student类中:
public class Student{
}
主类中:
Class<?> class1 = Class.forName("Demo1.Student");
System.out.println(class1.getName());
运行结果:
Demo1.Student
作用:获取类的简单名称(不包含包名)
返回值类型:String
代码演示:
Student类中:
public class Student{
}
主类中:
Class<?> class1 = Class.forName("Demo1.Student");
System.out.println(class1.getSimpleName());
运行结果:
Student
作用:获取类所在包的名称
返回值类型:String
代码演示:
Student类中:
public class Student{
}
主类中:
Class class1 = Class.forName("Demo1.Student");
System.out.println(class1.getPackage());
System.out.println(class1.getPackage().getName());
运行结果:
package Demo1
Demo1
作用:获取类的父类名称。
返回值类型:String
代码演示:
Person类中:
public class Person{//Person类没有指定继承的类,默认直接继承Object类
}
Student类中:
public class Student extends Person{//Student类继承了Person类
}
主类中:
Class class1 = Class.forName("Demo1.Person");
Class class2 = Class.forName("Demo1.Student");
System.out.println("Person类的父类:");
System.out.println(class1.getSuperclass());
System.out.println(class1.getSuperclass().getName());
System.out.println("Student类的父类:");
System.out.println(class2.getSuperclass());
System.out.println(class2.getSuperclass().getName());
运行结果:
Person类的父类:
class java.lang.Object
java.lang.Object
Student类的父类:
class Demo1.Person
Demo1.Person
作用:返回类所实现的所有接口
返回值类型:Class<?>[ ]
代码演示:
See接口:
public interface See{//看
}
Hear接口:
public interface Hear{//听
}
Smell接口:
public interface Smell{//闻
}
Taste接口:
public interface Taste{//尝
}
Person类:
public class Person implements See,Hear,Smell,Taste{//实现了看、听、闻、尝四个接口
}
主类中:
Class class1 = Class.forName("Demo1.Person");
Class[] class2 = class1.getInterfaces();
for(Class c : class2)
System.out.println(c);
运行结果:
interface Demo1.See
interface Demo1.Hear
interface Demo1.Smell
interface Demo1.Taste
Filed
类是反射中专门用于获取 类的属性 的类。
Filed类在获取获取类的属性之前,需要先获取类对象。
Student类:
public class Student{
String name;
private String gender;
}
主类中:
Class class1 = Class.forName("Demo1.Student");
Field name = class1.getField("name");//getField方法只能获取public修饰的属性
Field gender = class1.getDeclaredField("gender");//getDeclaredField方法可以获取任意访问修饰符修饰的属性
作用:设置访问修饰符是否有效,true为无效,false为有效,用于后续的修改。
返回值类型:void(无)
Student类中:
public class Student{
private String name;
}
主类中:
Class class1 = Class.forName("Demo1.Student");
Field name = class1.getDeclaredField("name");
name.setAccessible(false);//解除private的限制
作用:设置对象相应属性的属性值
返回值类型:void(无)
Student类中:
public class Student{
private String name;
private String gender;
private int age;
Student(){
}
Student(String name,String gender,int age){
this.name = name;
this.gender = gender;
this.age = age;
}
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
主类中:
Class class1 = Class.forName("Demo1.Student");
Field name = class1.getDeclaredField("name");
Field gender = class1.getDeclaredField("gender");
Field age = class1.getDeclaredField("age");
Student stu = new Student("张三","男",18);
System.out.println("修改前:");
System.out.println(stu);
name.setAccessible(true);//取消访问修饰符的限制
name.set(stu,"李娜");
gender.setAccessible(true);//取消访问修饰符的限制
gender.set(stu,"女");
age.setAccessible(true);//取消访问修饰符的限制
age.set(stu,22);
System.out.println("修改后:");
System.out.println(stu);
运行结果:
修改前:
Student{name=‘张三’, gender=‘男’, age=18}
修改后:
Student{name=‘李娜’, gender=‘女’, age=22}
Constructor类
是反射中专门用于获取 类的构造方法 的类。
需要处理异常:NoSuchMethodException
Constructor类在获取获取类的构造方法之前,需要先获取类对象。
Student类中:
public class Student{
private String name;
private String gender;
private int age;
public Student(){//使用了public修饰
}
Student(String name,String gender,int age){//未使用任何访问修饰符修饰
this.name = name;
this.gender = gender;
this.age = age;
}
}
主类中:
Class class1 = Class.forName("Demo1.Student");
//获取无参构造方法
//getConstructor方法只能构造方法必须是public
Constructor cons1 = class1.getConstructor();
//获取有参构造方法,参数为构造方法的类型
//getDeclaredConstructor方法可以访问任意修饰符修饰的方法
Constructor cons2 = class1.getDeclaredConstructor(String.class,String.class,int.class);
作用:创建具有无参构造方法,或具有多个参数方法的对象,需要向下转型。
返回值类型:Object
Student类中:
public class Student{
private String name;
private String gender;
private int age;
Student(){//无参构造方法
}
Student(String name,String gender,int age){//有参构造方法,没有使用修饰符修饰
this.name = name;
this.gender = gender;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
主类中:
Class class1 = Class.forName("Demo1.Student");
Constructor cons1 = class1.getDeclaredConstructor(String.class,String.class,int.class);
Student stu = (Student)cons1.newInstance("赵六","男",56);
Student stu2 = cons1.
System.out.println(stu);
运行结果:
Student{name=‘赵六’, gender=‘男’, age=56}
Method
是反射中专门用于获取 类的方法 的类。
需要处理异常:NoSuchMethodException
invoke:用于执行方法
Method类在获取获取类的方法之前,需要先获取类对象。
Student类中:
public class Student{
private String name;
private String gender;
private static int count;//学生数量
private int age;
public void show(){
System.out.println(name + " " + gender + " " + age + " ");
}
public void setName(String name){
this.name = name;
}
public void getName(){
return this.name;
}
public static int getStudentCount(){
return count;
}
}
主类中:
Class class1 = Class.forName("Demo1.Student");
//getmethod只能获取public修饰的方法
//获取无参无返回值方法
Method show = class1.getMethod("show");
//获取有参无返回值方法
Method setName = class1.getMethod("setName",String.class);
//获取有返回值的方法
Method getName = class1.getMethod("getName");
Student stu = new Student("张三","男",18);
String s = (String)getName.invoke(stu);
//获取静态方法
Method getStudentCount = class1.getMethod("getStudentCount");
int count = getStudentCount.invoke(null);
今天这篇文章讲解了反射,以及关于反射操作的四个类:Class、Filed、Constructor、Method。