“如何在 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 的异常体系,异常体系结构图如下:
程序在运行过程中发生由于硬件设备问题、软件设计错误等导致的程序异常事件。(在 Java 等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象。
如上面的 Java 异常体系结构图所示,Throwable有两个重要的子类:Exception(异常)和 Error(错误),两者都包含了大量的异常处理类。
(一)Error(错误)
程序中无法处理的错误,表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时 JVM 出现问题。通常有 Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如说当JVM 耗完可用内存时,将出现 OutOfMemoryError。此类错误发生时,JVM 将终止线程。
这些错误是不可查的,非代码性错误。因此,当此类错误发生时,应用不应该去处理此类错误。
(二)Exception(异常)
程序本身可以捕获并且可以处理的异常。
Exception 这种异常又分为两类:运行时异常和编译异常。
看完了Java的异常体系,我们知道上面代码出现的异常为编译时异常,是必须要处理的,否则无法通过编译阶段,更不要谈运行了。
既然上面代码不可用,那就请出本期的主角--- Java 的反射机制。
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。
在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法;
方法名称 | 返回值 | 参数 | 说明 |
---|---|---|---|
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 | 表示获取指定的一个本类中的方法(不包括继承的) |
Java 中,除了使用new关键字创建对象外,也可以用 newInstance() 方法创建对象,例如:
Class class1 = Class.forName("java.util.ArrayList");
List list=(List)class1.newInstance();
public Object invoke(Object obj,Object args[]) 作用:动态调用 Method 类代表的方法 obj:从中调用底层方法的对象,必须是实例化的对象 args:用于方法调用的参数,是个 Object 数组,因为参数有可能有多个 obj 可以为空,但必填 null,表示同类中的公用方法 args 参数可以为空,就是对应方法没有参数
有关 Java 反射的详细内容我将会专门出一期来讲解,这里只对本期用到的几个重要的知识点做概述。
看完了上面的内容,你是不是对面试官的问题有解答思路了呢?下面给出小编自己的想法,如果你有更好的方法,记得跟大家分享哦。
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;
}
}
作者: C you again,从事软件开发 努力在IT搬砖路上的技术小白 公众号: 【C you again】,分享计算机类毕业设计源码、IT技术文章、游戏源码、网页模板、程序人生等等 关于转载:欢迎转载博主文章,转载时标明出处 求赞环节:创作不易,记得 点赞+评论+转发 谢谢你一路支持