ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

面试官:五年经验,我不问问反射说不过去吧?

2020-11-13 09:35:20  阅读:163  来源: 互联网

标签:lang 反射 面试官 说不过去 java String 问问 Test public


1. 反射是什么?

反射是一种机制,是一种能力,是指JVM在运行过程中,对于任意一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意方法和属性

2. 反射的原理?

如果你对 JVM 的类加载机制有所了解(这里不了解也没关系),就会知道,类在编译的时候,会生成一个 .class 文件,当类被使用的时候,这个 class 文件就会被读取并被载入到虚拟机中,生成对应类型的 Class 对象,这个被创建出的 Class 对象中就包含了我们原本的类中一切信息,通过这个对象,我们就可以去获取这个类的属性和方法,并且把这些属性和方法转换成一个对象,从而达到改变/执行的目的。

3. 反射的使用?

使用反射的第一步,是获取一个 Class 对象,我们可以通过以下几种方式去获取一个 Class 对象

获取 Class 对象

// 1. 根据类的全限定名
Class str1 = Class.forName("java.lang.String");

// 2. .class获取
Class str2 = String.class;

// 3. 继承自 Object 类的 getClass 方法
String s = new String();
Class str3 = s.getClass();

拿到了 Class 对象,下面我就可以对这个 Class 对象进行进一步的剖析,获取它的构造方法,字段和一般方法

获取Constructor,Method,Filed

在获取之前,我们首先来新建个一个 Test 类来供我们使用

@Data
class Test {

    private String id;

    private String name;

    public String code;
}

这里需要⚠️注意,我在这里新建了两个private的字段和一个public 的字段,是为了给大家展示,即使是反射,也无法获取private的属性~

// 获取 constructor
Constructor[] constructors = test.getConstructors();
Arrays.stream(constructors).forEach(System.out::println);

System.out.println("------------------");

// 获取 filed
Field[] fields = test.getFields();
Arrays.stream(fields).forEach(System.out::println);

System.out.println("------------------");

// 获取 method
Method[] methods = test.getMethods();
Arrays.stream(methods).forEach(System.out::println);

打印的结果如下:

public show.shanhe.interview.reflection.Test()
------------------
public java.lang.String show.shanhe.interview.reflection.Test.code
------------------
public boolean show.shanhe.interview.reflection.Test.equals(java.lang.Object)
public java.lang.String show.shanhe.interview.reflection.Test.toString()
public int show.shanhe.interview.reflection.Test.hashCode()
public java.lang.String show.shanhe.interview.reflection.Test.getName()
public void show.shanhe.interview.reflection.Test.setName(java.lang.String)
public java.lang.String show.shanhe.interview.reflection.Test.getId()
public java.lang.String show.shanhe.interview.reflection.Test.getCode()
public void show.shanhe.interview.reflection.Test.setCode(java.lang.String)
public void show.shanhe.interview.reflection.Test.setId(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

Filed的打印中,我们可以看到只有code字段被打印了出来,其余两个private的字段并没有出现在我们打印的列表中。

拿到了方法,我们就可以用反射去执行方法

Method setName = test.getMethod("setName", String.class);
Test t = test.newInstance();
setName.invoke(t,"shanhe");
System.out.println(t.getName());

使用Methodinvoke方法,就可以去执行setName方法,这样就可以达到给对象赋值的目的~

关于反射的使用方法,到这里就告一段落,下面我们来看一下在项目中,我们如何使用反射去达到我们的目的,完成自动化的操作。

4. 反射的实际应用场景

在我们的实际业务开发中,我们很少用到反射去实现我们的业务功能,因为在业务执行的过程中,我们使用反射会使代码的执行效率变得很低,所以反射一般是应用在我们设计框架的时候去使用,我们平时使用到的一些框架和技术,其底层都是基于反射去实现的,简而言之,反射是用来造轮子的,那么反射造的轮子,我们日常项目开发中经常用到的有哪些呢?

说起 Spring 的特性,大多数人脑海中浮现的的下面这两个名字,其实这两个特性都是基于反射去实现的。

AOP

基于我们对 AOP 的了解,我们不难知道(如果不知道,请等待设计模式之代理模式的文章),AOP是基于动态代理去实现对方法的增强处理,那么动态代理类一般都会去继承InvocationHandler这个接口,然后通过重写接口中的invoke方法,就可以实现AOP所要达到的目的。

IOC

IOC的实现,实际上就是通过工厂模式+反射来完成的,首先,我们通过注解或者xml的方式,将类(Bean)注册到BeanFatory中,然后程序在执行的过程中,通过bean的全路径名,使用反射去获取一个对象实例

当然,这里没有列举出来的还有很多很多,比如文件的反编译,比如java的agent机制,比如tomcat,比如动态生成类的框架,几乎我们所能见到的框架中,都或多或少使用了反射这个神器来实现,反射的使用熟练程度,通常也是用来区分CRUD程序员和造轮子程序员的最大区别,也是进阶路上必不可少的一道坎儿,掌握了反射,我们就可以有更多的思路去实现,去优化我们的代码~

学会使用反射+设计模式这是一个成长的标志,所以,如果你有学到,请给我点赞+关注,这是给一个坚持原创的人最大的支持和鼓励,另外设计模式系列博客预热中,敬请期待~

标签:lang,反射,面试官,说不过去,java,String,问问,Test,public
来源: https://www.cnblogs.com/viyoung/p/13967576.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有