JAVA反射机制

目录

一、概念:

二、理解:

三、例子:

1、获取字节码信息的4种方式

1)通过实例的getClass()方法:

2)通过实例的class属性:      

3)通过Class.forName方法(最常用):

4)通过类加载器的loadClass方法:

2、Class类的实例的种类

1)普通类:

2)接口:

3)注解:

4)数组:

5)基本数据类型:

6)void:

3、获取构造器

1)获取所有public访问修饰符修饰的构造器

2)获取所有访问修饰符修饰的构造器

3)获取某个特定的构造器

4、创建对象

5、获取属性和对属性进行赋值

1)获取所有当前类和父类中public修饰的属性

2)获取所有当前类和父类中的属性

3)获取指定的属性

4)获取属性的具体结构

5)给属性赋值

6、获取方法和调用方法

1)获取访问修饰符public修饰的所有方法

2)获取所有访问修饰符修饰的所有方法

3)获取指定方法

4)获取方法的具体结构

5)调用方法

7、获取类的接口、所在包、注解

四、反射常见面试题

1、反射的使用场景?

2、反射是否破坏了面向对象的封装性?


一、概念:

        java反射机制是,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用这个对象的任意方法和属性;这种动态获取类信息和动态调用对象方法的功能,称为java语言的反射机制。

二、理解:

1)状态:运行状态
2)功能:
        a)对于任意一个类,都能够知道这个类的所有属性和方法;
        b)对于任意一个对象,都能够调用这个对象的任意方法和属性;

说明:在运行期间,如果要获取某个类的class对象,java虚拟机(JVM)会检查该类的class对象是否已被加载。如果没有被加载,JVM会根据类的完全路径名称找到对应的.class文件并加载到内存中并生成对应的class对象。一旦某个类型的class对象已被加载到内存中,就可以用这个class对象来产生该类型的所有实例对象。

三、例子:

1、获取字节码信息的4种方式

1)通过实例的getClass()方法:

    Person p1 = new Person();
    Class c1 = p1.getClass();

2)通过实例的class属性:      

    Class c2 = Person.class;

3)通过Class.forName方法(最常用):

    Class c3 = Class.forName("com.luke.Person");

4)通过类加载器的loadClass方法:

    ClassLoader classLoader = Test.class.getClassLoader();
    Class c4 = classLoader.loadClass("com.luke.Person");

2、Class类的实例的种类

1)普通类:

Class c1 = Person.class;

2)接口:

Class c2 = Comparable.class;

3)注解:

Class c3 = Override.class;

4)数组:

int[] arr1 = {1,2,3};
int[] arr2 = {4,5,6};
int[] arr3 = {7,8,9,10};

Class c4 = arr1.class;
Class c5 = arr2.class;
Class c6 = arr3.class;
System.out.println(c4 == c5); // true 相同纬度的数组为true
System.out.println(c4 == c6); // false 不相同纬度的数组为false

5)基本数据类型:

Class c7 = int.class;

6)void:

Class c8 = void.class;

3、获取构造器

1)获取所有public访问修饰符修饰的构造器

Constructor[] constructors = cls.getConstrutors();

2)获取所有访问修饰符修饰的构造器

Constructor[] constructors = cls.getDeclaredConstrutors();

3)获取某个特定的构造器

// getConstrutor(Class<?>... parameters)
// 默认空构造器
Constructor constructor1 = cls.getConstrutor(); 
// 有一个int参数的构造器
Constructor constructor2 = cls.getConstrutor(int.class); 
// 有一个double参数、int参数的构造器
Constructor constructor3 = cls.getConstrutor(double.class,int.class); 

// 同理,获取私有构造器
// 私有空构造器
Constructor constructor4 = cls.getDeclaredgetConstrutor(); 
// 有一个私有int参数的构造器
Constructor constructor5 = cls.getDeclaredgetConstrutor(int.class); 
// 有一个私有double参数、int参数的构造器
Constructor constructor6 = cls.getDeclaredgetConstrutor(double.class,int.class); 

4、创建对象

// 使用无参构造器创建对象
Object o1 = constructor1.newInstance();

// 使用有一个int参数的构造器创建对象
Object o2 = constructor2.newInstance(2);

// 使用有double.class,int.class的构造器创建对象
Object o3 = constructor2.newInstance(12.56,10);

5、获取属性和对属性进行赋值

1)获取所有当前类和父类中public修饰的属性

Field[] fields = cls.getFields();

2)获取所有当前类和父类中的属性

Field[] fields = cls.getDeclaredFields();

3)获取指定的属性

// 获取public的名称为name的属性
Field field = cls.getField("name");

// 获取private的名称为password的属性
Field field = cls.getDeclaredField("password");

4)获取属性的具体结构

// 1、获取属性的访问修饰符,是一个整数
int modifier = field.getModifiers(); // 1

// 可以通过Modifier.toString(modifier值)
System.out.println(Modifier.toString(modifier)); // 输出 public

// 2、获取属性的类型class对象
Class type = field.getType();

// 3、获取属性的名称
String name = field.getName();

说明:Modifier类是Java语言用于描述各种访问修饰符的类,各种访问修饰符有自己独有的int值表示对应的类型的访问修饰符,其中public使用1表示,static使用8表示,假如filed.getModifiers方法返回9,则表示由public和static同时修饰,可以使用Modifier.toString(modifier)打印出信息来;

5)给属性赋值

// 获取类的class对象
Class cls = Class.forName("com.luke.Person");
// 获取name属性
Field name = cls.getField("name");

// 给属性赋值时,必须要有实例对象
// 实例化对象
Object person = cls.newInstance();
// 给person实例name属性赋值
name.set(person,"张三");

6、获取方法和调用方法

1)获取访问修饰符public修饰的所有方法

Method[] methods = cls.getMethods();

2)获取所有访问修饰符修饰的所有方法

Method[] methods = cls.getDeclaredMethods();

3)获取指定方法

// getMethod(String name,Class<?>... parameters)方法
// 获取无参的play方法
Method method1 = cls.getMethod("play");

// 获取有String类型的参数的play方法
Method method2 = cls.getMethod("play",String.class);

4)获取方法的具体结构

// 获取注解前必须要指定方法
Method method = cls.getMethod("play");

// 获取方法名称
String name = method.getName();
// 获取方法的访问修饰符
int modifier = method.getModifiers();
System.out.println(Modifier.toString(modifier));
// 获取方法返回类型
Class returnType = method.getReturnType();
// 获取方法参数列表类型数组
Class[] parameterTypes = method.getParameterTypes();

// 获取方法的所有runtime类型的注解,即只有注解的@Retention(RetentionPolicy.RUNTIME)才能被获取
Annotation[] annotations = method.getAnnotations();
// 获取异常数组
Class[] exceptionTypes = method.getExceptionTypes();

5)调用方法

// 获取类的class对象
Class cls = Class.forName("com.luke.Person");
// 获取无参play方法
Method play1 = cls.getMethod("play");
// 获取有String类型参数的play方法
Method play2 = cls.getMethod("play",String.class);

// 调用方法时,必须要有实例对象
// 实例化对象
Object person = cls.newInstance();
// 调用person实例的无参play方法
play1.invoke(person);
// 调用person实例的有一个String类型参数的play方法
play2.invoke(person,"basketBall");

7、获取类的接口、所在包、注解

Class cls = Class.forName("com.luke.Person");
// 1、获取当前类的接口
Class[] interfaces = cls.getInterfaces();
// 获取父类的接口
Class superCls = cls.getSuperClass();
Class[] superInterfaces = superCls.getInterfaces();
// 2、获取当前类所在包
Package package = cls.getPackage();
// 3、获取当前类RUNTIME类型的注解
Annotation[] annotations = cls.getAnnotations();

四、反射常见面试题

1、反射的使用场景?

2、反射是否破坏了面向对象的封装性?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个的信息,并可以操作属性方法和构造器等。Java反射机制可以使程序员在运行时动态地调用方法属性,扩展的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件包含着的信息,这些信息包括的名称、方法属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存,然后通过加载器将加载到内存形成一个对象,这个对象可以操作字节码文件的信息。 使用Java反射机制的过程如下:首先获取对象,通过对象来获取的构造器、属性方法等信息,然后调用构造器来创建对象,通过属性获取和设置的成员属性,通过方法调用方法等。 Java反射机制的优点是可以在运行时动态地得到的信息,使得程序员在程序运行能够进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制Java语言的一项重要特性,在Java开发广泛应用,在代码编写、框架开发以及API开发具有重要作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值