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

智能推荐

lease 分布式_存储覆盖写和追加写-程序员宅基地

文章浏览阅读917次。背景和介绍缓存是计算机里广泛使用的一种技术,对降低读取延迟、网络流量和服务器负载都非常有效,但也带来了一致性(Consistency)的问题。所谓一致就是客户端总能读到最新的数据,使用缓存后有可能服务器端的数据已经被修改,但客户端仍然从缓存中读取陈旧的数据。为了保证一致性,有两种常见的解决办法,第一种是轮询(Polling),即每次读取数据时都先询问服务器数据是不是最新的,如果不是就从_存储覆盖写和追加写

java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double-程序员宅基地

文章浏览阅读5.8k次,点赞2次,收藏2次。报错:java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double原因:类型转换异常,这里要从map里面取出坐标点然后存起来,直接强转然后就报了错,网上查出来说是数据超长没办法直接强转,不知道原因对不对LatLng latLng = new LatLng((Double) aoLatLng.get("lng"), (Double) aoLatLng.get("lat"));解决办法:先toS_java.lang.classcastexception: java.math.bigdecimal cannot be cast to java.la

uniapp 项目双屏异显插件使用方式_uniapp分屏-程序员宅基地

文章浏览阅读4k次。本文主要记录uniapp双屏异显插件(安卓收银机双屏(副屏)异显,主副屏通讯)使用方式:在uniapp中安装和引入插件请参考uniapp文档,这里不作介绍uniapp里面调用调用也是参考插件文档进行的,直接贴源码吧!页面挂在成功后调用插件进行副屏显示 页面中的输入框和发送按钮模拟信息处理 send方法负责发送信息到副屏 /static/dist/index.html为打包的vue项目地址<template> <view> <input.._uniapp分屏

IIS真正能用的ISAPI-Rewrite防盗链规则写法-程序员宅基地

文章浏览阅读92次。本规则支持白名单排除式防盗链,搜索引擎友好不屏蔽,被盗链后的错误提示转向,支持各种文件类型,经作者亲验真的能用,第一时间在原创发表,请继续往下阅读。近来小站遇到了盗链问题,至使网站的流量枉费流失,于是被迫准备为服务器安装防盗链机制以挽救本就不宽裕的带宽。通过G.CN和B.CN搜索后得出了几种不同的方案,例如网站程序的URL伪装法、服务器端的收费插件法和ISAPI-R..._用易写isapi的筛选器,iis防盗链,谁会?讨论一下

python是什么和c++是什么区别_C++、Java和Python有什么不同?-程序员宅基地

文章浏览阅读2.5k次,点赞2次,收藏5次。C++、Java和Python都是面向对象的编程语言。其中C++和Java都是强类型语言,而Python是一种弱类型语言。一、python: 快速开发应用程序python比较容易学习,语法很简单,融入了很多现代编程语言的特性。python的库非常丰富,可以迅速地开发程序,无论是网站还是小游戏都非常方便。不过,python的脚本的运行效率较低,不适合对运行效率要求较高的程序。Python是一种脚本语..._python和c++什么关系

模型调参?拿来吧你~ —— CANape与Simulink的强强联手_vcdmstudio-程序员宅基地

文章浏览阅读1.8k次,点赞3次,收藏51次。前提概要: 随着ECU功能和标定需求不断增长,Vector公司的CANape在汽车行业颇负盛名。它主要用于ECU参数优化(标定),可在系统运行期间同时标定参数值和采集测量信号。其强大的离线数据分析、数据挖掘功能和集成的vCDMstudio(标定参数文件)都是工程师的得力助手。除此之外,CANape还结合Simulink,给模型调参提供良好的用户接口。由于MATLAB Scopes可视化功能有限,不足以支持工程师进行详细的数据分析。优化模型参数的过程费时费力——需修改MATLAB Workspace中的值_vcdmstudio

随便推点

gensim函数训练Word2Vec模型 具体参数讲解_gensim word2vec 参数-程序员宅基地

文章浏览阅读2.9k次。用gensim函数库训练Word2Vec模型有很多配置参数。这里对gensim文档的Word2Vec函数的参数说明进行翻译。class gensim.models.word2vec.Word2Vec(sentences=None,size=100,alpha=0.025,window=5, min_count=5, max_vocab_size=None, sample=0.001,seed=..._gensim word2vec 参数

Vue.js概述_vue.js是动态页面吗-程序员宅基地

文章浏览阅读265次。从头开始复习Vue.js3_vue.js是动态页面吗

django restframework ModelViewSet PUT方法不被允许_方法 “put” 不被允许。-程序员宅基地

文章浏览阅读4.1k次。默认的viewset和默认的router,但发送put、delete请求提示不支持官方实现update方法的时候要求传入pk,所以在put时将请求URL改成:path/pk/就可以了。正确的传参方式retrieve get/id/update put/id/destroy delect/id/list getpartial_update patchcreate post如果格式不正确 会显示" put 方法 不被允许..._方法 “put” 不被允许。

使用AD14创建异形PCB板_ad14导入dwg-程序员宅基地

文章浏览阅读7.8k次,点赞3次,收藏8次。前段时间同事需要按照AutoCAD的尺寸做一个PCB板。AD14支持导入DWG文件,于是选择了直接导入文件的方式来获得PCB板的外形尺寸。AutoCAD的尺寸图如下:打开Altium Designer 14.1,新建一个空白的PCB图。然后单击File->Import...打开导入文件对话框,在对话框里面文件类型选择AutoCAD(*.DXF, *.DWG),选_ad14导入dwg

【NOJ1001】【算法实验一】二分查找_给定递增整数序列l,其大小为n,要求使用二分查找法查找任意元素的位置k(序列中第几-程序员宅基地

文章浏览阅读533次。1001.二分查找时限:1000ms 内存限制:10000K 总时限:3000ms描述给定一个单调递增的整数序列,问某个整数是否在序列中。输入第一行为一个整数n,表示序列中整数的个数;第二行为n(n不超过10000)个整数;第三行为一个整数m(m不超过50000),表示查询的个数;接下来m行每行一个整数k。输出每个查询的输出占一行,如果k在序列中,输出Yes,否则输出No。输入样例51 3 4 7 113369输出样例YesNoNo#include <iostr_给定递增整数序列l,其大小为n,要求使用二分查找法查找任意元素的位置k(序列中第几

log4cplus最新介绍、详细编译过程及使用(最全面)-程序员宅基地

文章浏览阅读1.1w次,点赞19次,收藏86次。log4cplus是C++编写的开源的日志系统很有名也很强大,但网上大多的资料都是讲如何配置使用。关于编译过程一笔带过,尤其是windows下的编译过程少之又少。得先有编译这个提才有后续的使用,里面的坑也少有提及。以下对详细的编译过程和使用做个完整总结。log4cplus具有线程安全、灵活、以及多粒度控制的特点,通过将日志划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周期。你可以选择将日志输出到屏幕、文件、............................................_log4cplus