7Java基礎補充

1.標準Java bean寫法

包括:private修飾的成員變量、getter和setter以及無參和有多個參數的有參構造方法java

2.String原理

String底層是字節數組byte[]。數組

String不可變,但能夠被共享。緩存

3.Java中三種常量池:

(1)字符串常量池(全局字符串池):因爲字符串自己具備不可變性,所以使用字符串常量池對於一樣的字符串能夠起到一個緩存的做用,防止屢次內存分配,從而提供內存的利用率app

(2)運行時常量池:當程序運行到某個類的時候,class文件中的信息就會被解析到內存的方法區的運行時常量池中,每一個類都有一個運行時常量池。測試

(3)class文件常量池:class常量池是在編譯後每一個class文件都有的,class文件中除了包含類的版本 字段 方法 接口等描述信息,還有一項信息就是常量池,用於存放編譯器生成的各類字面量和符號的引用。優化

4.細化Java內存模型

從大的方面來講,JVM內存分爲幾個方面:ui

堆內存是JVM中最大的一塊區域,被全部線程共享,在JVM啓動時建立。幾乎全部對象的空間分配都在堆區來進行。spa

 

堆又分爲新生代和老年代內存,二者的內存大小的比例大概是1:2。線程

新生代又分爲Eden、From區和To區,三者的內存大小的比例大概是8:1:1。幾乎全部新對象的內存分配都在Eden區完成。code

劃分不一樣的區,分別保存不一樣的數據,其內存回收策略也不相同。

在GC中,Eden區活躍的對象會被移動到survivor區,不活躍的會被GC清理掉。Survivor區中的對象達到必定的年齡,就會被移動到老年代中。

堆內存能夠在物理上不連續,可是邏輯上要連續。

 

 

 

 

 方法區又被稱爲永久代,也是被全部的線程所共享的,該區域主要保存類的信息,靜態變量,常量和編譯器編譯後的代碼等數據。

 jdk7中,將永久代中的字符串常量池移動到堆中。jdk8 撤銷了永久代 ,引入了元空間                    

            

 

 

方法區不須要連續的內存,能夠選擇固定大小或者可擴展,而且還能夠選擇不實現垃圾回收,相對而言,垃圾收集行爲在這個區域是比較少見的,但並不是數據進入方法區就如永久代的名字同樣永久存在了。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載,圾回收機制的條件是至關苛刻的。

5.字符串的比較

public static void main(String[] args) {
   String s1 = "abc";
   String s2 = "abc";
   System.out.println(s1 == s2);//true,s1指向常量池中建立的對象地址,s2指向常量池中已經存在的對象地址,這個對象是相同的
   // 使用字符數組構造一個字符串
    char[] c = {'a','b','c'};
    String s3 = new String(c);
    String s4 = new String(c);
    System.out.println(s3 == s4);//false,堆中不一樣對象
    String s5 = new String("abc");
    String s6 = new String ("abc");
    System.out.println(s5==s6);// false,堆中不一樣對象
    System.out.println(s1 == s3);//false,s1指向常量池中建立的對象地址,s3指向堆中對象
    System.out.println(s4 == s5);//false,堆中不一樣對象
}
String str1 = "abc";//在常量池中建立對象並獲得引用
String str2 = new String("abc");//在堆中建立對象並引用,而後查看常量池,此時已經有對象,因此不用再建立
public static void main(String[] args) {
        String s1 = "hello";//常量池中建立hello的引用
        String s2 = "world";//常量池中建立world的引用
        String s3 = "hello" +"world";//常量池中建立helloworld的引用
        String s4 = s1 +"world";//堆中建立的對象的引用,至關於new StringBuilder(s1).append("world").toString();toString()建立一個新的堆對象。
        String s5 = s1 + s2;//堆中建立對象的引用,至關於//new StringBuilder(s1).append(s2).toString();
    String s6 = (s1 + s2).intern(); //該值在常量池中已經存在,返回s3的引用
    String s7
= "helloworld"; //該值在常量池中已經存在,返回s3的引用
    System.out.println(s3==s4);// false
    System.out.println(s3 == s7);//true
    System.out.println(s3==s5);//false
    System.out.println(s4==s5);//false
    System.out.println(s3==s6);//true }

+鏈接字符串:

常量+常量:編譯器直接優化生成結果,不須要生成StringBuilder。

常量+變量:須要生成StringBuilder,一行語句須要一個StringBuilder,append的數量基於變量和常量的個數,但當多個常量連在一塊兒時,編譯器會優化直接生成常量運算結果,算做一個append處理。

變量和變量:須要生成StringBuilder,一行語句須要一個StringBuilder,append的數量基於常量的個數

public static void main(String[] args) {
        String str1 = new StringBuilder("計算機").append("軟件開發").toString();
        System.out.println(str1.intern()== str1);//true,str1.intern()在常量池中建立一個指向str1的引用,因此相等
        String str2 = new StringBuilder("ja").append("va").toString();//java是一個特殊的字符串 在jdk的底層,存在不少「java」字符串
        System.out.println(str2.intern()==str2);//false,雖然沒有人爲建立,可是常量池中存在java對象,因此intern()返回的結果是常量池中的變量且不是ss堆對象的引用
 }
 public static void main(String[] args) {
      String str1 = new String("str") + new String("01");
      str1.intern();//intern()方法本質至關於把調用它的對象放入常量池,若是有就不放,並且放的是地址不是副本。
      String str2 = "str01";
        System.out.println(str1 == str2);//true
    }
  public static void main(String[] args) {
       String s1 = new String("he") +new String("llo");
       String s2 = new String("h") +new String("ello");
       String s3 = s1.intern();
       String s4 = s2.intern();
       System.out.println(s1==s3);//true
       System.out.println(s2 == s4);//false
       System.out.println(s3 == s4);//true
    }

6.抽象類

抽象類的語法格式:abstract class 類名{ }

抽象方法的語法格式:訪問修飾符 abstract 返回值 方法名( );

抽象類的特色:

  • 抽象類不能被直接實例化
  • 抽象類的子類必須實現抽象方法(除非這個子類也是抽象類)。
  • 抽象類裏能夠有普通方法,也能夠有抽象方法,可是有抽象方法的類必須是抽象類
  • 抽象類能夠沒有任何方法

7.接口

接口是一系列抽象方法的集合,與抽象類不一樣,不能夠聲明普通方法。

接口的語法格式:[修飾符] interface 接口名 [extends] [接口列表]{ 接口體 }

接口前面能夠用public修飾,省略控制修飾符該接口也是公開的。

extends 關鍵詞和類語法中的 extends 相似,用來定義直接的父接口。和類不一樣,一個接口能夠繼承多個父接口,當 extends 後面有多個父接口時,它們之間用逗號隔開。接口繼承接口的語法格式爲:[修飾符] class 類名 implements 接口列表{ 類體 }

類實現接口用 implements 關鍵字,Java 中的類只能是單繼承的但一個 Java 類能夠實現多個接口,這也是 Java 解決多繼承的方法。

接口下面不能夠有實體方法。

接口中能夠有成員變量,修飾符默認爲 public static final(即使不寫修飾符也默認是這樣),由於是常量因此必須在聲明時對這些成員變量賦初值。能夠這樣說,接口中的成員變量實際就是常量。

接口中的抽象方法默認且必須是 public 的。

接口 C 繼承接口 A 和 B,不一樣的方法都被直接繼承下來,相同的方法合併後被繼承下來

Java8以後,接口中能夠有默認/靜態方法,這個方法能夠有實體。

接口不能繼承抽象類,只能繼承其餘接口。

8.內部類

 

  • 成員內部類 成員內部類 InnerClass 能夠直接訪問外部類 OuterClass 中的屬性和方法,對於成員內部類的使用,須要先生成外部類對象,而後再以 外部類對象.new 內部類() 的形式生成內部類對象。
  • 靜態內部類 靜態內部類 InnerClass 只能訪問外部類  OuterClass  的靜態屬性和靜態方法,能夠經過類名直接調用,如 **類名.方法()**。與之相似,靜態內部類中的方法也能夠經過 **靜態內部類名.方法()** 的形式調用。若是測試類和靜態內部類不在同一個.java文件中,那麼能夠經過 **外部類名.靜態內部類.方法()** 的形式調用。
  • 局部內部類    JDK8.0 之後,局部內部類 `InnerClass` 在訪問外部方法 `method()` 定義的變量時,能夠省略給變量加 final 修飾。局部內部類只能在定義它的方法內部使用,局部內部類的定義並不會影響外部類方法的使用。

 

  • 匿名內部類
相關文章
相關標籤/搜索