Java面试复习2 java的多态,异常处理及常用API(String,StringBuffer,StringBuilder类,Math类)_java stringbuffer 异常处理-程序员宅基地

技术标签: java面试与一些基础复习  

Java面试复习2 java的多态,异常处理及常用API

声明:本面试复习都基于一本未署名的Java面试宝典所述,根据自己的理解写出了这一专栏的复习博客

  1. Java中实现多态的机制是什么?
    简单来说就是定义一个父类的,或者接口类型的引用变量指向子类或者接口实现类的实例对象现在A是B的父类 Public A a = new B();这就是一种多态性的体现通过这种方式,父类定义的变量可以调用子类中的重写方法,而且在程序的运行时完成动态的绑定,而不再调用父类或者接口类型中的方法

  2. java中的异常处理
    首先要清楚异常按照处理时机分为两种,一种是编译时异常CheckedException(也叫强制性异常),一种是运行时异常RuntimeException(也叫非强制性异常)
    前者作为Java所特有的异常,在编译时期如果代码出现错误就将停止编译,编译器给出的两种处理方式为:try/catch:(当前方法知道怎么处理异常)
    抛出异常(当前方法不知道怎么处理异常)
    而后者是在实际开发中会经常碰到的错误,仅发生在代码运行时的异常,诸如空指针异常,除数为0的算术异常,数组下标越界等,一般情况下这些异常由系统捕获在控制台上显示给程序员,当然如果你想要获取这个异常的文本也可以手动捕获并输出或者增加操作,但这个并不会阻止当前程序的运行终止,该终止还是终止。

  3. 调用下图中方法,返回值是什么?
    在这里插入图片描述
    在这里插入图片描述
    正确答案:3 (感谢一楼纠错…)
    在这里我们需要认识一个点,当try/catch中的catch中遇到了return的时候,需要执行完整个try/catch结构再执行catch中的语句,正确的执行顺序为:try->catch(检查到其中有return)->finally->catch(再执行一遍)
    {这个代码的执行顺序是没错的,不过在finally中由于是return语句,而不是空操作或者赋值操作,那么当return执行后整个方法代码便结束了,也就回不到上面去了。}

        public static int i;
        @Test
        public void testTest(){
          
            int a = returnTest();
            System.out.println(a);//此时返回的便是2
        }
        public int returnTest(){
          
            try{
          
                int a = 1/0;
                i = 1;
            }catch (Exception e){
          
                i = 2;
                return i;
            }
            finally {
          
                i = 3;
            }
            return i;
        }
    
  4. error和exception的区别?
    在这里插入图片描述

  5. Java的异常处理机制
    在这里插入图片描述

  6. 请写出5个最常见的RuntimeException
    NullpointException:空指针异常,当调用不存在或者未初始化对象的变量的时候会发生
    ClassNotFoundException:找不到指定类,当调用类的时候类名和路径加载错误时会发生,通常是程序员试图通过字符串来家在某个类的时候发生
    NumberFormatException:字符串转换为数字发生异常,当被转换的字符串中不仅仅是数字的时候会发生
    SQLException:SQL异常,当SQL语句错误时发生异常
    ClassCastException:数据类型转换异常
    IndexOutOfBoundsException:数组下标越界异常,当操作数组对象时操作数多于其长度会发生
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  7. throw和throws的区别

    1. throw用于方法体内,表示抛出异常,由方法体内的语句处理。
    2. throw是具体向外抛出异常的动作,所以他抛出的是一个异常实例,执行throw一定是抛出了某种异常,是处理
    3. throws使用在方发声明后面,表示如果抛出了异常,由该方法的调用者来进行处理。
    4. throws主要是声明这个方法会抛出什么类型的异常,让调用该方法的对象明白,需要按照相同的,或者更高级别的异常类型来处理。
    5. throws表明一种异常发生的可能性,是防范,并不一定会发生异常
  8. final,finally,finalize的区别

    1. final:用于声明属性方法和类,一旦声明,则所声明属性不可更改,所声明方法不能覆盖,所声明类不能被继承
    2. finally:异常处理try/catch语句中的一个部分,无论try/catch语句中发生什么,总是执行
    3. finalizeObject类中的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时其他资源的回收。可以理解为,某个对象的该方法一旦被调用,就意味着被调用的对象的生命周期的结束,但是值得注意的是,该方法不能被主动调用,而是被动的被调用(属于一种回调),因此如果我们主动调用该方法的时候,对象的生命周期并不会结束。
  9. JavaSE的常用API

    1. 如图
      在这里插入图片描述
      答案:12 , 11 四舍五入不必多说
      这个时候我们来复习一下Math这个类的用法。
      更具体的参考下述博文https://blog.csdn.net/xuexiangjys/article/details/79849888

      Math.sqrt() : 计算平方根
      Math.cbrt() : 计算立方根
      Math.pow(a, b) : 计算a的b次方
      Math.max( , ) : 计算最大值
      Math.min( , ) : 计算最小值
      Math.abs() : 取绝对值
      abs 绝对值 
      acos,asin,atan,cos,sin,tan 三角函数 
      sqrt 平方根 
      pow(double a,doble b) a的b次幂 
      log 自然对数 exp e为底指数 
      max(double a,double b) 
      min(double a,double b) 
      random() 返回0.01.0的随机数 
      long round(double a) double型数据a转换为long型(四舍五入) 
      toDegrees(double angrad) 弧度—>角度 
      toRadians(double angdeg) 角度—>弧度
      //Math.random,产生随机数
      	public static void main(String[] args) {
              
      		double r =   Math.random();
      		// 0 --100 
      		System.out.println(r);
      		Random random = new Random();
      		int i = random.nextInt();
      		System.out.println(i);
      		int i1 = random.nextInt(50);//0--50 不包括50
      		System.out.println(i1);
      	}
      
    2. switch能否作用在byte上,能否作用在long上,能否作用在String上?
      答案:byte,String(在JDK7之后可以)可以,long不行
      这个其实算是对switch语句的一个检查,和对java版本的一个知悉程度。
      在这里我们借助此题完成复习,需要知道的是

      1. switch(表达式)中表达式的值必须是下述几种类型之一:byte,short, char,int,枚举类型enum(jdk 5.0),String (jdk 7.0)
      2. case子句中的值必须是常量,不能是变量名或不确定的表达式值;
        同一个switch语句,所有case子句中的常量值互不相同;
      3. break语句用来在执行完一个case分支后使程序跳出switch语句块;如 果没有break,程序会顺序执行到switch结尾
      4. default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时, 执行default
    3. 数组有没有length()方法,String呢?
      答案:数组是没有的,但是每个数组都具有一个lenth属性String则是有该方法的。

    4. String,StringBuilder,StringBuffer的区别。
      Java提供了两种类型的字符串:一类是String,另一类则是StringBuilder/StringBuffer,都可以储存和操作字符串。
      区别:

      1. String是只读的字符串,也就意味着,它引用的字符串内容不能发生改变的,具体我们可以思考一下字符串常量池的概念就可以很好地理解了。
        在这里插入图片描述
        在这里插入图片描述
      2. StringBuilder/StringBuffer表示的字符串对象是可以修改的。
      3. 如图,前者效率在理论上比后者高
        在这里插入图片描述
    5. 什么情况下,使用"+"运算符进行字符串连接比调用StringBuilder/StringBuffer对象的append方法连接字符串的性能更好?
      这个例题直接粘作者的解析,因为我也不是很懂,刚刚理解的样子,比较多,如下。
      总结就是,在一些简单的情况下,"+"和StringBuilder/StringBuffer的底层效果其实是相同的,+的底层也是转换成了StringBuilder/StringBuffer,但是复杂情况下,比如 +在涉及到循环时会有多次在循环中创建StringBuilder/StringBuffer的对象 ,而这种做法在程序中显然是不合适的,占用了太多的内存空间,并且产生的垃圾也会变多,不可取,因此后者的性能显然是更好的,即便是前者会令开发的程序语言显得简洁一些。但是后者依然在整个过程中更为合适。当然值得注意的是StringBuilder/StringBuffer两者之间也是有区别的,前者在JDK1.4之前并没有在API中提供使用,因此之前的版本是不存在他的,在J2SE5及以上版本之后,才有提供,由于后者是线程安全的,前者是线程不安全的,除去安全性的考虑,单考虑效率方面,前者的效率会更高。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      拓展思考:String,StringBuilder/StringBuffer类的了解
      String:不可变字符串 类中的一些方法。

      int length():返回字符串的长度: return value.length 
      char charAt(int index): 返回某索引处的字符return value[index] 
      boolean isEmpty():判断是否是空字符串:return value.length == 0 
      String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写 
      String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写 
      String trim():返回字符串的副本,忽略前导空白和尾部空白 
      boolean equals(Object obj):比较字符串的内容是否相同 
      boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大 小写 
      String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+int compareTo(String anotherString):比较两个字符串的大小 
      String substring(int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex开始截取到最后的一个子字符串。 
      String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字 符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
      boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 
      boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始 
      boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的 子字符串是否以指定前缀开始
      boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列 时,返回 true
      int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引 
      int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出 现处的索引,从指定的索引开始 
      int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引 
      int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后 一次出现处的索引,从指定的索引开始反向搜索 注:indexOf和lastIndexOf方法如果未找到都是返回-1
      String replace(char oldChar, char newChar):返回一个新的字符串,它是 通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 
      String replace(CharSequence target, CharSequence replacement):使 用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 
      String replaceAll(String regex, String replacement) : 使 用 给 定 的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 
      String replaceFirst(String regex, String replacement) : 使 用 给 定 的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
      boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
      String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 
      String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此 字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
      

      String与基本数据类型之间的转换:

      字符串 --> 基本数据类型、包装类 
      Integer包装类的public static int parseInt(String s):可以将由“数字”字 符组成的字符串转换为整型。 
      类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应 的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。 
      基本数据类型、包装类 --->字符串 
      调用String类的public String valueOf(int n)可将int型转换为字符串 
      相应的valueOf(byte b)valueOf(long l)valueOf(float f)valueOf(double d)valueOf(boolean b)可由参数的相应类型到字符串的转换
      
      字符数组 -->字符串
      String 类的构造器:String(char[])String(char[]int offset,int length) 分别用字符数组中的全部字符和部分字符创建字符串对象。
      字符串 -->字符数组 
      public char[] toCharArray():将字符串中的全部字符存放在一个字符数组 中的方法。 
      public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):提供了将指定索引范围内的字符串存放到数组中的方法。
      字节数组 -->字符串 
      String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构 造一个新的 String。
      String(byte[]int offset,int length) :用指定的字节数组的一部分, 即从数组起始位置offset开始取length个字节构造一个字符串对象。
      字符串 -->字节数组 
      public byte[] getBytes() :使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 
      public byte[] getBytes(String charsetName) :使用指定的字符集将 此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
      

      StringBuilder/StringBuffer:可变字符串 区别在于前者线程不安全,效率高,后者线程安全,效率低。下列是一些方法,这两个都适用

      StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接 
      StringBuffer delete(int start,int end):删除指定位置的内容 
      StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str 
      StringBuffer insert(int offset, xxx):在指定位置插入xxx 
      StringBuffer reverse() :把当前字符序列逆转
      
      public int indexOf(String str) 
      public String substring(int start,int end) 
      public int length() 
      public char charAt(int n ) 
      public void setCharAt(int n ,char ch)
      
    6. 下列程序的输出为:
      这是对于整个String和StringBuffer/StringBuilder,字符串常量池和intern的理解,
      首先是String.intern()
      String.intern()是一个Native方法,底层调用C++的 StringTable::intern 方法,源码注释:当调用 intern 方法时,如果常量池中已经该字符串,则返回池中的字符串;否则将此字符串添加到常量池中,并返回字符串的引用。

      在知道了这个前提下。
      我们需要知道,s1创建了一个"Programing"常量存放在字符串常量池中,s2在堆内存中new了一个地址值,这个地址值中并没有我们所要的"Programing"常量,而是又指向了字符串常量池中的"Programing"常量,s3创建了一个"Progra"常量存放在字符串常量池中,s4创建了一个"ming"常量存放在字符串常量池中,s5进行拼接后,首先在字符串常量池中搜寻是否有对应的拼接后的"Programing"常量值的存在,答案是有的,那就不用创建了,让s5直接指向了"Programing"的位置,s6则是在变量的基础上进行的,这时候就需要翻底层操作了,也就是他需要

      1. 运行期JVM首先会在堆中创建一个StringBuilder类,
      2. 同时用s3指向的拘留字符串对象(intern字符串对象)完成初始化,
      3. 然后调用append方法完成对s4所指向的拘留字符串的合并,
      4. 接着调用StringBuilder的toString()方法在堆中创建一个String对象,
      5. 最后将刚生成的String对象的堆地址存放在局部变量s6中

      而他指向的肯定是在堆内存中的地址,而不再是指向常量池中的常量了。所以我们可以由此得出下列结果了,但是当他重新调用intern方法时,就又指向了常量池中的常量了,对于intern来说,new过的对象,JDK6的执行结果为:false
      JDK7和JDK8的执行结果为:true,原因是6中字符串常量池并不再堆内存中,而7和8在堆内存中了,具体的原理解释可以看下列博文,讲述的非常详细:
      https://blog.csdn.net/qq_34490018/article/details/82110578
      在这里插入图片描述
      在这里插入图片描述
      因此就可以得出上述结论了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36763661/article/details/104306638

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法