Java最新图解java反射机制及常用应用场景,javaio面试题面试题

总结

谈到面试,其实说白了就是刷题刷题刷题,天天作死的刷。。。。。

为了准备这个“金三银四”的春招,狂刷一个月的题,狂补超多的漏洞知识,像这次美团面试问的算法、数据库、Redis、设计模式等这些题目都是我刷到过的

并且我也将自己刷的题全部整理成了PDF或者Word文档(含详细答案解析)

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

66个Java面试知识点

架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

算法刷题(PDF)

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • java.lang.annotation.Annotation:在类、成员变量、构造方法、普通方法上都可以加注解

4.1.获取Class对象的三种方法

Class.forName()方法获取Class对象

/**

* Class.forName方法获取Class对象,这也是反射中最常用的获取对象的方法,因为字符串传参增强了配置实现的灵活性

*/

Class cls = Class.forName("com.zimug.java.reflection.Student");



类名.class获取Class对象

/**

* `类名.class`的方式获取Class对象

*/

Class clz = User.class;



类对象.getClass()方式获取Class对象

/**

* `类对象.getClass()`方式获取Class对象

*/

User user = new User();

Class clazz = user.getClass();



虽然有三种方法可以获取某个类的Class对象,但是只有第一种可以被称为“反射”。

4.2.获取Class类对象的基本信息


Class cls = Class.forName("com.zimug.java.reflection.Student");



//获取类的包名+类名

System.out.println(cls.getName());          //com.zimug.java.reflection.Student

//获取类的父类

Class cls = Class.forName("com.zimug.java.reflection.Student");

//这个类型是不是一个注解?

System.out.println(cls.isAnnotation());     //false

//这个类型是不是一个枚举?

System.out.println(cls.isEnum());      //false

//这个类型是不是基础数据类型?

System.out.println(cls.isPrimitive()); //false



Class类对象信息中几乎包括了所有的你想知道的关于这个类型定义的信息,更多的方法就不一一列举了。还可以通过下面的方法

  • 获取Class类对象代表的类实现了哪些接口: getInterfaces()

  • 获取Class类对象代表的类使用了哪些注解: getAnnotations()

4.3. 获得Class对象的成员变量

结合上文中的Student类的定义理解下面的代码


Class cls = Class.forName("com.zimug.java.reflection.Student");



Field[] fields = cls.getFields();

for (Field field : fields) {

System.out.println(field.getName());      //nickName

}



fields = cls.getDeclaredFields();

for (Field field : fields) {

System.out.println(field.getName());      //nickName 换行  age

}



  • getFields()方法获取类的非私有的成员变量,数组,包含从父类继承的成员变量

  • getDeclaredFields方法获取所有的成员变量,数组,但是不包含从父类继承而来的成员变量

4.4.获取Class对象的方法

  • getMethods() : 获取Class对象代表的类的所有的非私有方法,数组,包含从父类继承而来的方法

  • getDeclaredMethods() : 获取Class对象代表的类定义的所有的方法,数组,但是不包含从父类继承而来的方法

  • getMethod(methodName): 获取Class对象代表的类的指定方法名的非私有方法

  • getDeclaredMethod(methodName): 获取Class对象代表的类的指定方法名的方法


        Class cls = Class.forName("com.zimug.java.reflection.Student");



        Method[] methods = cls.getMethods();

        System.out.println("Student对象的非私有方法");

        for (Method m : methods) {

            System.out.print(m.getName() + ",");

        }

        System.out.println("  end");



        Method[] allMethods = cls.getDeclaredMethods();

        System.out.println("Student对象的所有方法");

        for (Method m : allMethods) {

            System.out.print(m.getName() + ",");

        }

        System.out.println("  end");



        Method dinnerMethod = cls.getMethod("dinner");

        System.out.println("dinner方法的参数个数" + dinnerMethod.getParameterCount());



        Method sleepMethod = cls.getDeclaredMethod("sleep",int.class);

        System.out.println("sleep方法的参数个数" + sleepMethod.getParameterCount());

        System.out.println("sleep方法的参数对象数组" + Arrays.toString(sleepMethod.getParameters()));

        System.out.println("sleep方法的参数返回值类型" + sleepMethod.getReturnType());



上面代码的执行结果如下:


Student对象的非私有方法

dinner,wait,wait,wait,equals,toString,hashCode,getClass,notify,notifyAll,  end



Student对象的所有方法

dinner,sleep,  end



dinner方法的参数个数0

sleep方法的参数个数1

sleep方法的参数对象数组[int arg0]

sleep方法的参数返回值类型void



可以看到getMethods获取的方法中包含Object父类中定义的方法,但是不包含本类中定义的私有方法sleep。另外我们还可以获取方法的参数及返回值信息:

  • 获取参数相关的属性:

    • 获取方法参数个数:getParameterCount()

    • 获取方法参数数组对象:getParameters() ,返回值是java.lang.reflect.Parameter数组

  • 获取返回值相关的属性

    • 获取方法返回值的数据类型:getReturnType()

4.5.方法的调用

实际在上文中已经演示了方法的调用,如下invoke调用dinner方法


Method dinnerMethod = cls.getDeclaredMethod("dinner");

dinnerMethod.invoke(obj);  //打印:吃晚餐!



dinner方法是无参的,那么有参数的方法怎么调用?看看invoke方法定义,第一个参数是Method对象,无论后面Object... args有多少参数就按照方法定义依次传参就可以了。


public Object invoke(Object obj, Object... args)



4.6.创建类的对象(实例化对象)


//获取Student类信息

Class cls = Class.forName("com.zimug.java.reflection.Student");

//对象实例化

Student student = (Student)cls.getDeclaredConstructor().newInstance();

//下面的这种方法是已经Deprecated了,不建议使用。但是在比较旧的JDK版本中仍然是唯一的方式。

//Student student = (Student)cls.newInstance();



五、反射的常用场景


  • 通过配置信息调用类的方法

  • 结合注解实现特殊功能

  • 按需加载jar包或class

5.1. 通过配置信息调用类的方法

将上文的hello world中的代码封装一下,你知道类名className和方法名methodName是不是就可以调用方法了?至于你将className和 methodName配置到文件,还是nacos,还是数据库,自己决定吧!


public void invokeClassMethod(String className,String methodName) throws ClassNotFoundException, 

            NoSuchMethodException, 

            InvocationTargetException, 

            InstantiationException, 

            IllegalAccessException {

        //获取类信息

        Class cls = Class.forName(className);

        //对象实例化

        Object obj = cls.getDeclaredConstructor().newInstance();

        //根据方法名获取并执行方法

        Method dinnerMethod = cls.getDeclaredMethod(methodName);

        dinnerMethod.invoke(obj);

}



5.2.结合注解实现特殊功能

大家如果学习过mybatis plus都应该学习过这样的一个注解TableName,这个注解表示当前的实体类Student对应的数据库中的哪一张表。如下问代码所示,Student所示该类对应的是t_student这张表。


@TableName("t_student")

public class Student {

    public String nickName;

    private Integer age;

}



下面我们自定义TableName这个注解


@Target(ElementType.TYPE)  //表示TableName可作用于类、接口或enum Class, 或interface

@Retention(RetentionPolicy.RUNTIME) //表示运行时由JVM加载

public @interface TableName {

       String value() ;   //则使用@TableName注解的时候: @TableName(”t_student”);

}



有了这个注解,我们就可以扫描某个路径下的java文件,至于类注解的扫描我们就不用自己开发了,引入下面的maven坐标就可以


<dependency>

    <groupId>org.reflections</groupId>

    <artifactId>reflections</artifactId>

    <version>0.9.10</version>

</dependency>



看下面代码:先扫描包,从包中获取标注了TableName注解的类,再对该类打印注解value信息


// 要扫描的包

String packageName = "com.zimug.java.reflection";

Reflections f = new Reflections(packageName);

// 获取扫描到的标记注解的集合

Set<Class<?>> set = f.getTypesAnnotatedWith(TableName.class);

for (Class<?> c : set) {

// 循环获取标记的注解

TableName annotation = c.getAnnotation(TableName.class);

// 打印注解中的内容

System.out.println(c.getName() + "类,TableName注解value=" + annotation.value());



输出结果是:


com.zimug.java.reflection.Student类,TableName注解value=t_student



有的朋友会问这有什么用?这有大用处了。有了类定义与数据库表的对应关系,你还能通过反射获取类的成员变量,之后你是不是就可以根据表明t_student和字段名nickName,age构建增删改查的SQL了?全都构建完毕,是不是就是一个基础得Mybatis plus了?

反射和注解结合使用,可以演化出许许多多的应用场景,特别是在框架代码实现方面。等待你去发觉啊!

5.3.按需加载jar包或class

在某些场景下,我们可能不希望JVM的加载器一次性的把所有classpath下的jar包装载到JVM虚拟机中,因为这样会影响项目的启动和初始化效率,并且占用较多的内存。我们希望按需加载,需要用到哪些jar,按照程序动态运行的需求取加载这些jar。

把jar包放在classpath外面,指定加载路径,实现动态加载。



# 2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

**目录:**

![](https://img-blog.csdnimg.cn/img_convert/62337a469a6d116c40cdeab2e64cf05f.webp?x-oss-process=image/format,png)

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

![](https://img-blog.csdnimg.cn/img_convert/054e594c16688b300a4a760b73c9f6e1.webp?x-oss-process=image/format,png)

**部分内容:**

![](https://img-blog.csdnimg.cn/img_convert/25677e67df682076403442839fb45bcb.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/48c4aba883ce169c8af147ea27065645.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/5325d0577a3220b39905ef2536cfb3b6.webp?x-oss-process=image/format,png)



对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,**高清完整版一共是888页,需要的话可以点赞+关注**


> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

—剖析面试题——完美解答的一个过程)

[外链图片转存中...(img-R2WMt40R-1715428661830)]

**部分内容:**

[外链图片转存中...(img-bAQoFto1-1715428661830)]

[外链图片转存中...(img-AEyoGfQJ-1715428661831)]

[外链图片转存中...(img-YvjDzen2-1715428661831)]



对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,**高清完整版一共是888页,需要的话可以点赞+关注**


> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值