• 面试官:如何在Integer类型的ArrayList中同时添加String、Character、Boolean等类型的数据? | Java反射高级应用


    原文链接:原文来自公众号:C you again,欢迎关注!

    1、问题描述

        “如何在Integer类型的ArrayList中同时添加String、Character、Boolean等类型的数据?”

        你是不是想到下面的代码?

    package com.cya.test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test{
    
        public static void main(String []args){
    
            List<Integer> list=new ArrayList<>();
            Integer in=1;
            Character ch='c';
            Boolean bo=true;
            list.add(in);
            list.add(ch);
            list.add(bo);
            System.out.println(list);
    
        }
    
    }
    

        有点Java基础的人都知道上面的代码运行会报错,如果使用Eclipse等开发工具的话在没运行之前就会提示有错了,如下图:

    在这里插入图片描述
    在这里插入图片描述

        强制运行一波,看下错误提示:

    Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
        The method add(Integer) in the type List<Integer> is not applicable for the arguments (Character)
        The method add(Integer) in the type List<Integer> is not applicable for the arguments (Boolean)
    
        at com.cya.test.Test.main(Test.java:15)
    

        听说英语差的都去当程序员了!!

        不过没关系,能get到大体意思就好了,上面的错误大体意思如下:

    程序在编译时遇到了无法解析的错误,
    add方法的参数是Integer类型,无法接收Character类型的参数,
    add方法的参数是Integer类型,无法接收Boolean类型的参数

        上面代码错误的原因是程序无法通过编译,在编译期出现异常,这和Java是编译性语言(如:C、C++、Delphi、Pascal、Java)有关。与解释性语言(如:Basic、javascript、Python)不同,Java先将后缀名为.java的源代码文件编译成后缀名为.class的字节码文件,编译期间会进行词法、语法、数据类型、语义分析。上面的错误就是在编译期间进行数据类型分析时类型不匹配造成的。

        谈到这里,我们不得不提下Java的异常体系,异常体系结构图如下:
    在这里插入图片描述

    2、什么是异常

        程序在运行过程中发生由于硬件设备问题、软件设计错误等导致的程序异常事件。(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。

    3、异常体系分类

        如上面的Java异常体系结构图所示,Throwable有两个重要的子类:Exception(异常)和Error(错误),两者都包含了大量的异常处理类。

        (一)Error(错误)
        程序中无法处理的错误,表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时JVM出现问题。通常有Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如说当JVM耗完可用内存时,将出现OutOfMemoryError。此类错误发生时,JVM将终止线程。

        这些错误是不可查的,非代码性错误。因此,当此类错误发生时,应用不应该去处理此类错误。

        (二)Exception(异常)
        程序本身可以捕获并且可以处理的异常。

        Exception这种异常又分为两类:运行时异常和编译异常。

    1. 运行时异常(不受检异常):RuntimeException类及其子类表示JVM在运行期间可能出现的错误。比如说试图使用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。

    2. 编译异常(受检异常):Exception中除RuntimeException及其子类之外的异常。如果程序中出现此类异常,比如说IOException,必须对该异常进行处理,否则编译不通过。在程序中,通常不会自定义该类异常,而是直接使用系统提供的异常类。

        看完了Java的异常体系,我们知道上面代码出现的异常为编译时异常,是必须要处理的,否则无法通过编译阶段,更不要谈运行了。

        既然上面代码不可用,那就请出本期的主角---Java的反射机制。

    4、反射的概述

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

    5、反射机制的作用

    在运行时判断任意一个对象所属的类;
    在运行时构造任意一个类的对象;
    在运行时判断任意一个类所具有的成员变量和方法;
    在运行时调用任意一个对象的方法;

    6、反射的三种实现方式

    1. 通过对象的getClass()方法。getClass()方法是Object类的方法,因为所有类都继承自Object类,所以可以直接使用getClass()方法。
    2. 通过类名.class属性。如果知道类的名称,可以直接获取一个类的Class。
    3. 通过Class类的forName(parameter)方法(常用)。这种方式是最常用的,在各类框架的配置文件中可以看到,如:Spring、SpringMVC、Mybatis等等。其中,参数parameter为全限定类名(即:包名+类名),如:com.cya.test.Test。

    7、通过反射获取类中的方法

    方法名称 返回值 参数 说明
    getMethods() Method [] 获取包括自身和继承过来的所有的public方法
    getDeclaredMethods() Method [] 获取自身类中所有的方法(不包括继承的,和访问权限无关)
    getMethod(String methodName,Class<?>... parameterTypes) Method methodName:表示被获取方法的名字parameterTypes:表示被获取方法的参数的Class类型,如String.class 表示获取指定的一个公共的方法(包括继承的)
    getDeclaredMethod(String methodName,Class<?>... parameterTypes) Method methodName:表示被获取方法的名字parameterTypes:表示被获取方法的参数的Class类型,如 String.class 表示获取指定的一个本类中的方法(不包括继承的)

    8、通过反射创建对象

        java中,除了使用new关键字创建对象外,也可以用newInstance()方法创建对象,例如:

    Class class1 = Class.forName("java.util.ArrayList");
    List list=(List)class1.newInstance();
    

    9、Method类的invoke()方法

    public Object invoke(Object obj,Object args[])
    作用:动态调用Method类代表的方法
    obj:从中调用底层方法的对象,必须是实例化的对象
    args:用于方法调用的参数,是个Object数组,因为参数有可能有多个
    obj可以为空,但必填null,表示同类中的公用方法
    args参数可以为空,就是对应方法没有参数

        有关Java反射的详细内容我将会专门出一期来讲解,这里只对本期用到的几个重要的知识点做概述。

        看完了上面的内容,你是不是对面试官的问题有解答思路了呢?下面给出小编自己的想法,如果你有更好的方法,记得跟大家分享哦。

    10、思路分享

    1、创建Integer类型的List集合,用于存放数据。
    2、使用对象名.getClass()方法获取Class对象。
    3、调用getMethod()方法获取指定的Method。
    4、调用invoke()方法将不同数据类型的数据添加到list集合中。

    11、代码实现

    package com.cya.test;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test{
    
        public static void main(String []args) throws Exception{
    
            List<Integer> list=new ArrayList<>();
            Object o;
    
            //向list中添加Integer类型的数据
            Integer integer=1;
            o=integer;
            Test.addObjectToList(list, o);
    
            //向list中添加String类型的数据
            String string="Hello World";
            o=string;
            Test.addObjectToList(list, o);
    
            //向list中添加Character类型的数据
            Character character='c';
            o=character;
            Test.addObjectToList(list, o);
    
            //向list中添加Boolean类型的数据
            Boolean boolean1=true;
            o=boolean1;
            Test.addObjectToList(list, o);
    
            System.out.println(list);
    
        }
    
    public static List<Integer> addObjectToList(List<Integer> list, Object o) throws Exception{
    
            Class class1=list.getClass();
            Method method=class1.getMethod("add", Object.class);
            method.invoke(list, o);
            return list;
        }
    
    }
    

    12、公众号推荐(资源加油站)

    了解更多资源请关注个人公众号:C you again,你将收获以下资源

    1、PPT模板免费下载,简历模板免费下载
    2、基于web的机票预订系统基于web的图书管理系统
    3、贪吃蛇小游戏源码
    4、各类IT技术分享

    在这里插入图片描述

    13、文章推荐

    推荐一:计算机网络中这些高频考题,你还在死记硬背吗?(一),讲述内容:IP地址及其分类,子网掩码的概念,网络号、主机号、直接广播地址计算方法等。

    推荐二:计算机网络中这些高频考题,你还在死记硬背吗?(二),讲述内容:局域网接口配置、路由器的静态路由配置、OSPF动态路由协议配置和DHCP服务器配置。

    推荐三:用x种方式求第n项斐波那契数,99%的人只会第一种,讲述内容:七种方式求解第N项斐波那契数。

        以上就是本期的所有内容了,是否对你有帮助呢?了解更多算法请关注公众号“C you again”。

    演示地址:点击查看演示

  • 相关阅读:
    Maven的声明周期(Lifecycle )和命令(Phase)
    Java并发之线程异常捕获
    Java并发之需要了解但不能太依赖的东东
    ejs使用
    node.js BootStrap安装
    div+css关于overflow 动态滚动效果
    myBatis 参数配置
    jQuery Ajax请求提交 后台getParameter接收不到数据
    mysql+mybatis 插入可递增字段库表操作
    CSS浮动讲解好文章推荐
  • 原文地址:https://www.cnblogs.com/cafuc20160512056/p/13387127.html
Copyright © 2020-2023  润新知