【Java】---反射:Class、Filed、Constructor、Method

发布时间:2024年01月24日

【Java】—反射



一、反射

1.1 概念

把Java类中的各种成分映射成单独的Java对象进行操作。
换言之,如果类是小白鼠的话,反射就是对其一系列的解剖操作。
类中的成分包括:类和类的成员信息类的构造方法类的方法类的属性

对于类中的这些成分,有专门的类用于获取:
Class类:可获取类和类的成员信息。
Field类:可访问类的属性。
Method类:可调用类的方法。
Constructor类:可调用类的构造方法。

1.2 操作步骤

反射的操作步骤有以下这些:

  1. 获取类对象。
  2. 获取类的基本信息。
  3. 获取类的构造方法。
  4. 获取类的方法。
  5. 获取类的属性。

二、Class类

2.1 概念

Class类是 类的类型 ,每一个类都是Class类的实例,每个类只有一个Class实例(类对象)。
Class类是反射中专门用于获取 类和类的成员信息 的类。

需要处理异常:ClassNotFoundException
ClassNotFoundException

类对象的创建共有三种方式:

  1. 通过类的实例获取。(此方法耦合性高,不推荐)
Student zhangsan = new Student();
Class<?> class1 = zhangsan.getClass();
  1. 通过class属性获取。(此方法耦合性高,不推荐)
Class<?> class2 = Student.class;
  1. 通过静态方法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;
    }

    @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

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。

文章来源:https://blog.csdn.net/qq_54185425/article/details/135781683
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。