反射概述
- Java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用再编译期就完成确定,在运行期仍然可以扩展
我们以下的例子都是基于这个学生类Student来操作,下面是学生类Student的代码
学生类有:
静态属性:
- 私有-介绍-String-introduce
成员属性:
- 公共-姓名-String-name-;
- 默认-编号-int-no;
- 私有-年龄-int-age
构造方法:
- 公共构造方法,Student()
- 默认构造方法,Student(String name, int age)
- 私有构造方法,Student(String name, int no, int age)
静态方法:
- private static String introduce()
成员方法
- 公共无参无返回值方法:public void love()
- 默认无参无返回值方法:void lovelorn()
- 私有带参无返回值方法:private void love(Student s)
- 私有无参有返回值方法:private String dream()
- 重写toString方法
package com.testReflex;
/**
* @author 林高禄
* @create 2020-06-05-16:49
*/
public class Student {
// 静态属性
private static final String INTRODUCE="这是学生类";
// 成员属性:一个公共,一个默认,一个私有
public String name;
int no;
private int age;
// 构造器,一个公共,一个默认,一个私有
public Student() {
}
Student(String name, int age) {
this.name = name;
this.age = age;
}
private Student(String name, int no, int age) {
this.name = name;
this.no = no;
this.age = age;
}
// 静态方法
public static String introduce(){
System.out.println(INTRODUCE);
return INTRODUCE;
}
// 成员方法:一个公共,一个默认,一个私有带参,一个私有有返回值
public void love(){
System.out.println("暗恋中!");
}
void lovelorn(){
System.out.println("失恋了!");
}
private void love(Student s){
System.out.println("正在和【"+s.name+"】谈恋爱!");
}
private String dream(){
return "好好学日语!";
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", no=" + no +
", age=" + age +
'}';
}
}
获取Class类的对象
我们要想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象,这里我们提供三种方式获取Cass类型的对象
- 使用类的class属性来获取该类对应的Class对象。举例:Student.class将会返回Student类对应的Class对象
- 调用对象的getClass()方法,返回该对象所属类对应的Class对象,该方法是Object中的方法,所有的Java对象都可以调用该方法
- 使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
package com.testReflex;
/**
* @author 林高禄
* @create 2020-06-05-17:02
*/
public class GetClassDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 使用类的class属性来获取该类对应的Class对象
Class<Student> studentClass = Student.class;
System.out.println(studentClass);
Class<Student> studentClass2 = Student.class;
System.out.println(studentClass == studentClass2);
// 调用对象的getClass()方法,返回该对象所属类对应的Class对象
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
System.out.println(studentClass == aClass);
// 使用Class类中的静态方法forName(String className)
Class<?> aClass1 = Class.forName("com.testReflex.Student");
System.out.println(studentClass == aClass1);
}
}
运行输出:
class com.testReflex.Student
true
true
true
从输出三个true可以看出,通过这三种方法获取的类的对象都是同一个对象
反射获取构造方法并使用
calss类中用于获取构造方法的方法
- Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
- Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
- Constructor<T> getConstructor(Class<?>...parameterTypes):返回单个公共构造方法对象
- Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
反射获取构造方法
package com.testReflex;
import java.lang.reflect.Constructor;
import java.util.stream.Stream;
/**
* @author 林高禄
* @create 2020-06-07-10:41
*/
public class GetConstructorDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// 使用Class类中的静态方法forName(String className)
Class<?> c = Class.forName("com.testReflex.Student");
System.out.println("-----------构造方法的获取-----------");
// 获取公共的构造方法
System.out.println("获取公共的构造方法");
Constructor<?>[] publicConstructors = c.getConstructors();
Stream.of(publicConstructors).forEach(System.out::println);
// 获取所有的构造方法
System.out.println("获取所有的构造方法");
Constructor<?>[] allConstructors = c.getDeclaredConstructors();
Stream.of(allConstructors).forEach(System.out::println);
// 获取单个公共的构造方法
System.out.println("获取单个公共的构造方法");
Constructor<?> publicConstructor = c.getConstructor();
System.out.println(publicConstructor);
// 报错Exception in thread "main" java.lang.NoSuchMethodException: com.testReflex.Student.<init>(java.lang.String, int)
// 没有这样的方,因为getConstructor(Class<?>...parameterTypes)只能获取公共的
Constructor<?> defaultConstructor = c.getConstructor(String.class, int.class);
}
}
运行输出:
-----------构造方法的获取-----------
获取公共的构造方法
public com.testReflex.Student()
获取所有的构造方法
private com.testReflex.Student(java.lang.String,int,int)
com.testReflex.Student(java.lang.String,int)
public com.testReflex.Student()
获取单个公共的构造方法
public com.testReflex.Student()
Disconnected from the target VM, address: 'javadebug', transport: 'shared memory'
Exception in thread "main" java.lang.NoSuchMethodException: com.testReflex.Student.<init>(java.lang.String, int)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.testReflex.getConstructorDemo.main(getConstructorDemo.java:29)
后面的报错是因为getConstructor(Class<?>...parameterTypes)只能获取公共的构造方法,要获取默认和私有的还得用Constructor<?>[] getDeclaredConstructor(Class<?>...parameterTypes)
package com.testReflex;
import java.lang.reflect.Constructor;
/**
* @author 林高禄
* @create 2020-06-07-10:41
*/
public class GetConstructorDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodExc

本文详细探讨了Java反射机制,包括如何获取Class对象、反射获取和使用构造方法、成员变量和成员方法。通过实例展示了反射如何越过泛型检查,使能装Student的集合也能装其他数据类型。同时,展示了反射在动态配置中的应用,通过修改配置文件即可改变程序运行时调用的方法。
最低0.47元/天 解锁文章

601

被折叠的 条评论
为什么被折叠?



