【Java】—反射
文章目录
- 【Java】---反射
- 一、反射
- 1.1 概念
- 1.2 操作步骤
- 二、Class类
- 2.1 概念
- 2.2 方法
- 2.2.1 getName()
- 2.2.2 getSimpleName()
- 2.2.3 getPackage()
- 2.2.4 getSuperclass()
- 2.2.5 getInterfaces()
- 三、Field类
- 3.1 概念
- 3.2 方法
- 3.2.1 setAccessible(Boolean b)
- 3.2.2 set(Object obj,Object value)
- 四、Constructor
- 4.1 概念
- 4.2 方法
- 4.2.1 newInstance(参数1,参数2,..)
- 五、Method
- 5.1 概念
- 总结
一、反射
1.1 概念
把Java类中的各种成分映射成单独的Java对象进行操作。
换言之,如果类是小白鼠的话,反射就是对其一系列的解剖操作。
类中的成分包括:类和类的成员信息、类的构造方法、类的方法、类的属性。
对于类中的这些成分,有专门的类用于获取:
Class
类:可获取类和类的成员信息。
Field
类:可访问类的属性。
Method
类:可调用类的方法。
Constructor
类:可调用类的构造方法。
1.2 操作步骤
反射的操作步骤有以下这些:
- 获取类对象。
- 获取类的基本信息。
- 获取类的构造方法。
- 获取类的方法。
- 获取类的属性。
二、Class类
2.1 概念
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");
2.2 方法
2.2.1 getName()
作用:获取类的全名称(包含包名)
返回值类型:String
代码演示:
Student类中:
public class Student{
}
主类中:
Class<?> class1 = Class.forName("Demo1.Student");
System.out.println(class1.getName());
运行结果:
Demo1.Student
2.2.2 getSimpleName()
作用:获取类的简单名称(不包含包名)
返回值类型:String
代码演示:
Student类中:
public class Student{
}
主类中:
Class<?> class1 = Class.forName("Demo1.Student");
System.out.println(class1.getSimpleName());
运行结果:
Student
2.2.3 getPackage()
作用:获取类所在包的名称
返回值类型: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
2.2.4 getSuperclass()
作用:获取类的父类名称。
返回值类型: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
2.2.5 getInterfaces()
作用:返回类所实现的所有接口
返回值类型: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
三、Field类
3.1 概念
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方法可以获取任意访问修饰符修饰的属性
3.2 方法
3.2.1 setAccessible(Boolean b)
作用:设置访问修饰符是否有效,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的限制
3.2.2 set(Object obj,Object value)
作用:设置对象相应属性的属性值
返回值类型: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
4.1 概念
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);
4.2 方法
4.2.1 newInstance(参数1,参数2,…)
作用:创建具有无参构造方法,或具有多个参数方法的对象,需要向下转型。
返回值类型: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;}@Overridepublic 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
5.1 概念
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。