Java中反射、枚举及lambda表达式的使用

一、反射

1.1 定义

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制

1.2 用途

1、在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法
2、反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无论是XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的就是类的信息,spring根据这些信息,需要创建哪些Beanspring就动态的创建这些类。

1.3 反射基本信息

Java程序中许多对象在运行时会出现两种类型运行时类型(RTTI)和编译时类型,例如Person p = newStudent();这句代码中p在编译时类型为Person,运行时类型为Student。程序需要在运行时发现对象和类的真实信息。而通过使用反射程序就能判断出该对象和类属于哪些类

1.4 与反射相关的类

类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量/类的属性
Method类 代表类的方法
Constructor类 代表了类的构造方法

1.5 Class类(反射机制的起源 )

Class代表类的实体,在运行的Java应用程序中表示类和接口 .

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个类文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类 .

1.6 Class类中的相关方法

常用获得类相关的方法:

方法 用途
getClassLoader() 获得类的加载器
getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的)
forName(String className) 根据类名返回类的对象
newInstance() 创建类的实例
getName() 获得类的完整路径名字

常用获得类中属性相关的方法(以下方法返回值为Field相关)

方法 用途
getField(String name) 获得某个公有的属性对象
getFields() 获得某个公有的属性对象
getDeclaredField(String name) 获得某个属性对象
getDeclaredFields() 获得某个属性对象

获得类中注解相关的方法

方法 属性
getAnnotation(Class annotationClass) 返回该类中与参数类型匹配的公有注解对象
getAnnotations() 返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass)
getDeclaredAnnotations() 返回该类所有的注解对象

获得类中构造器相关的方法(以下方法返回值为Constructor相关)

方法 属性
getConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的公有构造方法
getConstructors() 获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的构造方法
getDeclaredConstructors() 获得该类中所以构造方法

1.7 获得Class对象的三种方式

在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息。

第一种,使用 Class.forName("类的全路径名"); 静态方法。
前提:已明确类的全路径名。

第二种,使用 .class 方法。
说明:仅适合在编译前就已经明确要操作的 Class

第三种,使用类对象的 getClass() 方法。

代码示例:
本节代码均在一个包下面。

package reflectTest;

class Student{
   
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
   
        System.out.println("Student()");
    }
    private Student(String name,int age) {
   
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }
    private void eat(){
   
        System.out.println("i am eat");
    }
    public void sleep(){
   
        System.out.println("i am pig");
    }
    private void function(String str) {
   
        System.out.println(str);
    } @
            Override
    public String toString() {
   
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class test01 {
   
    public static void main(String[] args) {
   
        try {
   
            //通过 Class 对象的 forName() 静态方法来获取,用的最多,
            //但可能抛出 ClassNotFoundException 异常
            Class<?> c1 = Class.forName("reflectTest.Student");
            //直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
            //这说明任何一个类都有一个隐含的静态成员变量 class
            Class<?> c2 = Student.class;
            //通过getClass获取Class对象
            Student student = new Student();
            Class<?> c3 = student.getClass();


            System.out.println(c1.equals(c2));
            System.out.println(c1.equals(c3));
            System.out.println(c2.equals(c3)
  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值