JavaSE經常使用API

  一、Math.round(11.5)等於多少?Math.round(-11.5)又等於多少?java

    Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11.四捨五入的原理是在參數上加0.5而後進行取整。面試

  

  二、switch是否能做用在byte上,是否能做用在long上,是否能做用在String上?安全

    Java5之前switch(expr)中,expr只能是byte、short、char、int。從Java5開始,Java引入了枚舉類型,expr也能夠是enum類型數據結構

    從Java7開始expr還能夠是字符串String,可是長整型(long)在目前全部的版本中都是不能夠的app

  

  三、String、StringBuilder、StringBuffer的區別?工具

    Java平臺提供了兩種類型的字符串:String和StringBuffer/StringBuilder,它們均可以儲存和操做字符串,區別以下。性能

      1)String(最終類)是隻讀字符串,也就意味這String引用的字符串內容是不可改變的。初學者可能會有這樣的誤解:ui

          String str = "abc";spa

          str = "bcd";線程

        如上、字符串str明明是能夠改變的呀,其實否則,str僅僅是一個引用對象,它指向一個字符串對象「abc」。第二行代碼的含義是讓str從新指向了一個新的字符串「bcd」對象,而「abc」對象並無任何改變,只不過該對象已經成爲了一個不可及對象(GC將要回收的對象)罷了。

      2)StringBuilder/StringBuffer表示的字符串對象能夠直接進行修改。

      3)StringBuilder是Java5引入的,它和StringBuffer的方法徹底相同,區別在於它是在單線程環境下使用的,由於它的全部方法都沒有被synchronized修飾,所以它的小輪理論上也要比StringBuffer要高。

 

   四、什麼狀況下用「+」運算符進行字符串鏈接比調用StringBuilder/StringBuffer對象的append方法鏈接字符串性能更好?

    字符串是Java程序最經常使用的數據結構之一。在Java中String類已經重載了「+」。也就是說,字符串能夠直接使用」+「進行鏈接,以下面代碼所示:

    String s = "abc" + "def";

    但這樣作真的好嗎?固然,這個問題不能簡單的回答yes or no 。要根據具體狀況來定。在Java中提供了一個StringBuilder類(Java5之後版本提供),這個類也能夠起到」+「的做用。那麼咱們應該用哪一個呢?

    下面咱們先看看以下的代碼:

      package string ;

        public class TestSimplePlus{

          public static void main(String[] args){

              String s = "abc";

              String ss = "ok" + s + "xyz" + 5;

              System.out.println(ss);

            }

        }

    上面的代碼將會輸出正確的結果。從表面看,對字符串和整型使用」+「並無什麼區別,但事實真的如此嗎?下面讓咱們開看看這段代碼的本質。

    咱們首先使用反編譯工具(如 jdk 帶的 javap、或 jad)將 TestSimplePlus 反編譯成 Java Byte Code,其中的奧祕就一目瞭然了。在本文將使用 jad 來反編譯,命令以下:jad -o -a -s d.java TestSimplePlus.class
      反編譯後的代碼以下:

      

  讀者可能看到上面的 Java 字節碼感到迷糊,不過你們沒必要擔憂。本文的目的並非講解 Java Byte Code,所以,並不用瞭解具體的字節碼的含義。使用 jad 反編譯的好處之一就是能夠同時生成字節碼和源代碼。這樣能夠進行對照研究。從上面的代碼很容易看出,雖然在源程序中使用了"+",但在編譯時仍然將"+"轉換成 StringBuilder。所以,咱們能夠得出結論,在 Java 中不管使用何種方式進行字符串鏈接,實際上都使用的是 不管使用何種方式進行字符串鏈接,實際上都使用的是 StringBuilder 。那麼是否是能夠根據這個結論推出使用"+"和 StringBuilder 的效果是同樣的呢?這個要從兩個方面的解釋。若是從運行結果來解釋,那麼"+"和 StringBuilder 是徹底等效的。但若是從運行效率和資源消耗方面看,那它們將存在很大的區別。固然,若是鏈接字符串行表達式很簡單(如上面的順序結構),那麼"+"和 StringBuilder 基本是同樣的,但若是結構比較複雜,如使用循環來鏈接字符串,那麼產生的 Java Byte Code 就會有很大的區別。先讓咱們看看以下的代碼

    

    你們能夠看到,雖然編譯器將「+」轉換成了StringBuilder,但建立StringBuilder對象的位置卻在for語句內部。這就意味着每執行一次循環,就會建立一個StringBuilder對象(對於本例來講,是建立了10個StringBuilder對象),雖然Java有垃圾回收器,但這個回收器的工做時間是不定的。若是不斷產生這樣的垃圾,那麼仍然會佔用大量的資源。解決這個問題的方法就是在程序中直接使用StringBuilder來鏈接字符串,代碼以下:

    

    上面代碼反編譯後的結果以下所示:

    

    從上面的反編譯結果能夠看出,建立StringBuilder的代碼被放在了for語句外。雖然這樣處理在源程序中看起來複雜,但卻換來了更好的效率,一樣的消耗的資源也更少了。

    4在使用StringBuilder時要注意,儘可能不要「+」和StringBuilder混着用,不然會建立更多的StringBuilder對象,以下面代碼所示:

    

    改爲以下形式:

    

    則反編譯後的結果以下:

    

    從上面的代碼能夠看出,Java編譯器將「+」編譯成了StringBuilder,這樣for語句每循環一次,又建立了一個StringBuilder對象。

    若是將上面的代碼在JDK1.4下編譯,必須將StringBuilder改成StringBuffer,而JDK1.4將「+」轉換爲StringBuffer。StringBuffer和StringBuilder的功能基本同樣,只是StringBuffer是線程安全的,而StringBuilder不是線程安全的。所以,StringBuilder的效率會更高。

    

    六、請說出下面程序的輸出

      

    補充:解答上面的面試題須要知道以下兩個知識點:

      1)String對象的intern()方法會獲得字符串對象在常量池對應的版本中的引用(若是常量池中有一個字符串與String對象的equals結果是true),若是常量池中沒有對應的字符串,則該字符串被添加到常量池中,而後返回常量池中字符串的引用;

      2)字符串的+操做其本質是建立了StringBuilder對象進行append操做,而後將拼接後的StringBuilder對象用toString方法處理成爲String對象,這一點能夠用javap -c StringEqualTest.class命令得到class文件對應的JVM字節碼指令就能夠看出來。

相關文章
相關標籤/搜索