java語言基礎

来源:http://www.cnblogs.com/yqxx1116/archive/2016/11/05/6033733.html
-Advertisement-
Play Games

一、OOP(Object-oriented Programming)面向對象程式編程 初談類和對象,所謂萬物皆對象,類和對象有什麼區別和聯繫? 類,是對某一種類型的定義,比如字元串,動物,人,飛機等等,而對象是指具體的字元串,動物,人... 如:豬是類,定義了,豬,有體重,有年齡,可以吃飯,可以睡覺 ...


一、OOP(Object-oriented Programming)面向對象程式編程

  初談類和對象,所謂萬物皆對象,類和對象有什麼區別和聯繫?

  類,是對某一種類型的定義,比如字元串,動物,人,飛機等等,而對象是指具體的字元串,動物,人...

  如:豬是類,定義了,豬,有體重,有年齡,可以吃飯,可以睡覺,而對象是這隻豬,那隻豬,或者某隻豬起個名字,叫小白,那麼這種具體的豬,就是對象,而小白這個名字,則稱為對象的引用,因為通過小白,我們可以找到指定的那頭豬。

package com.yq;

public class Pig {

    private int height;
    private int age;

    void eat() {
        System.out.println("eat()");
    }

    void sleep() {
        System.out.println("sleep()");
    }

    public String toString() {
        return getClass().getName() + "===@===" + Integer.toHexString(hashCode());
    }
//    public String toString() {
//        return getClass().getName() + "@" + Integer.toHexString(hashCode());
//    }

    public static void main(String[] args) {

        Pig xiaoBai = new Pig();
        Pig xiaoHei = new Pig();
        xiaoBai.eat();
        xiaoHei.sleep();
        System.out.println(xiaoBai);
        System.out.println(xiaoHei);
        System.out.println("xiaoBai==xiaoHei?" + (xiaoBai == xiaoHei));
        System.out.println(xiaoBai.getClass());
        System.out.println(xiaoHei.getClass());
        System.out.println("xiaoBai.getClass()==xiaoHei.getClass()?" + (xiaoBai.getClass() == xiaoHei.getClass()));
    }
}
eat()
sleep()
com.yq.Pig===@===74a14482
com.yq.Pig===@===1540e19d
xiaoBai==xiaoHei?false
class com.yq.Pig
class com.yq.Pig
xiaoBai.getClass()==xiaoHei.getClass()?true

關於 '=='

    對於引用變數而言,比較的時候兩個引用變數引用的是不是同一個對象,即比較的是兩個引用中存儲的對象地址是不是一樣的。

    對於基本數據類型而言,比較的就是兩個數據是不是相等。

 

 對於String類型,它是特殊而有趣的。

package com.yq;

public class Test {

    public static void main(String[] args) {
        //String作為一個對象來使用
        System.out.println("String作為一個對象來使用");
        String str = new String("hello");
        String str2 = "he" + new String("llo");
        System.out.println("str==str2?" + (str == str2));
        System.out.println(str + "@" + str.hashCode());
        System.out.println(str2 + "@" + str2.hashCode());
        //String作為一個基本類型來使用
        //如果String緩衝池內不存在與其指定值相同的String對象,那麼此時虛擬機將為此創建新的String對象,並存放在String緩衝池內。
        //如果String緩衝池記憶體在與其指定值相同的String對象,那麼此時虛擬機將不為此創建新的String對象,而直接返回已存在的String對象的引用。
        System.out.println("String作為一個基本類型來使用");
        String s1 = "java";
        String s2 = "java";
        System.out.println("s1==s2?" + (s1 == s2));
        System.out.println(s1 + "@" + s1.hashCode());
        System.out.println(s2 + "@" + s2.hashCode());
        System.out.println("String混合使用");
        String st1 = "hello java";
        String st2 = new String("hello java");
        System.out.println("st1==s2?" + (st1 == st2));
        System.out.println(st1 + "@" + st1.hashCode());
        System.out.println(st2 + "@" + st2.hashCode());
    }
}
String作為一個對象來使用
str==str2?false
hello@99162322
hello@99162322
String作為一個基本類型來使用
s1==s2?true
java@3254818
java@3254818
String混合使用
st1==s2?false
hello java@-1605094224
hello java@-1605094224

輸出結果中,明明hashCode相等,為何對象不相同?

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

上述String源碼中,可以看出,String類是使用它的 value值作為參數然後進行運算得出hashcode的,
換句話說, 只要值相同的String不管是不是一個對象,hash值全部相等。

在Object超類中,hashCode()是一個native本地方法,看不到實現。

對象存放在記憶體的堆中,而基本類型則存放在記憶體的棧中。

 

二、操作符

 移位操作符<<,>>,>>>

  移位操作符操作的對象是二進位的"位",只能用來處理整數類型,如果對char、byte、或者short類型的數值進行移位處理,那麼他們在移位之前會自動轉換為int類型,結果也是int,對long處理,結果也是long。

  <<      :     左移運算符,低位補0,num << 1,相當於num乘以2

  >>      :     右移運算符,若符號為正,高位補0,若符號為負,高位補1,num >> 1,相當於num除以2

  >>>    :     無符號右移,忽略符號位,空位都以0補齊。

 三元操作符  exp?value1:value2

  若exp表達式為true,返回value1的值,否則返回value2的值,三元表達式可以嵌套。

 '+'操作符,即字元串操作符,用來連接字元串。

 '()type'類型轉換操作符,用來強制類型轉換,一般自動向上轉型,不需要強轉,向下轉型才需要強轉。

 ','逗號操作符,java裡面唯一用到逗號操作符的地方就是for迴圈的控製表達式,在表達式的初始化和步進控制部分,可以使用逗號分隔的語句,但是初始化時,使用逗號表達式,必須具有想同的類型。

三、流程式控制制

  if-else、while、do-while、for、foreach、switch。

  if語句不加{},預設範圍為下一條語句。

  else if不是關鍵字,只是else後面加了一個if語句。

  do-while相比while只是會先執行一次,再判斷條件。

  for(;;)效果和while(true)一樣。

  foreach語法用於數組和容器。

package com.yq;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        for (int i : arr)
            System.out.print(i + " ");
        System.out.println();
        List<String> ls = new ArrayList();
        ls.add("a");
        ls.add("b");
        ls.add("c");
        ls.add("d");
        ls.add("e");
        for (String str : ls)
            System.out.print(str + " ");
    }
}

//out
1 2 3 4 5 
a b c d e

關鍵字return、break、continue。

return結束整個方法,開始下一個方法。

break結束當前層的迴圈,開始當前層的外層的下一次迴圈。

continue結束當前層的當次迴圈,開始當前層的下一次迴圈。

switch的選擇因數,是一個能夠產生整數值的表達式,char本身就是整數。

四、類初始化

 this關鍵字

  1、表示當前類對象的引用

  2、表示對調用當前方法的那個對象的引用

  3、構造器調用類中的其他構造器,但是不能調用兩次,並且必須放在構造器的第一行。

 static關鍵字

  static靜態方法,可以通過類本身直接調用,當然類對象也可以調用static方法,但是static方法裡面不能調用非靜態方法,也不能出現this。

  對於static修飾的類屬性來說,記憶體只為該屬性第一次初始化時分配一個地址,不管該類new了多少個對象,該屬性都是同一個引用。

  雖然地址是唯一的,即引用是唯一的,但是引用的值還是可以改變的。

 final關鍵字

  final作用於方式,則該方法不能被繼承時覆蓋,作用於參數,如果是引用類型,則該引用不能改變,但是引用的對象可以改變,如果是基本類型,則只能被賦值一次,並且不能改變。

 對於一個類說來,該類的成員屬性,可以不初始化,因為系統會為各成員屬性設置預設值,String、對象等預設為null,數值類型為0,對應folat或者double,也有相應的小數點,char也為0,顯示為空白,boolean為false,String、對象則為null。

 只有類成員屬性會被預設初始化,方法中必須對定義的屬性或變數初始化。

 初始化順序

      構造器不指定時,系統將會設置一個預設無參構造器,若指定了一個構造器,無論是否有參數,系統都不會自動設置預設構造器。

  下麵的例子,詳細分析了,各種情況的初始化順序:

package com.yq;

class Animal {
    static int level;
    int type;

    static {
        System.out.println("Animal static");
        level = 1;
        System.out.println("Animal level:" + level);
    }

    {
        System.out.println("Animal");
        type = 10;
    }

    Animal(int i) {
        System.out.println("Animal constructor");
    }
}

class Pig extends Animal {
    static int level;
    int height;
    Eye eye = new Eye(2);

    static {
        System.out.println("Pig static");
        level = 2;
        System.out.println("Pig level:" + level);
    }

    {
        System.out.println("Pig");
        height = 20;
        super.level = 3;
    }

    Pig(int i) {
        super(i);
        System.out.println("Pig constructor");
    }
}

class Eye {
    Eye(int i) {
        System.out.println(i + "隻眼睛");
    }
}

public class Test {
    public static void main(String[] args) {
        //測試1
        Pig pg1 = new Pig(2);
        System.out.println(Animal.level);
        //測試2
        Pig pg2 = new Pig(2);
        Pig pg3 = new Pig(2);
        System.out.println(Animal.level);
        //測試3
        System.out.println(Pig.level);
    }
}
//測試1輸出
Animal static
Animal level:1
Pig static
Pig level:2
Animal
Animal constructor
2隻眼睛
Pig
Pig constructor
3
//測試2輸出
Animal static
Animal level:1
Pig static
Pig level:2
Animal
Animal constructor
2隻眼睛
Pig
Pig constructor
Animal
Animal constructor
2隻眼睛
Pig
Pig constructor
3
//測試3輸出
Animal static
Animal level:1
Pig static
Pig level:2
2

由測試1可知,初始化順序為:父類靜態成員、父類靜態代碼塊、子類靜態成員,子類靜態代碼塊、父類成員,父類代碼塊,父類構造器、子類成員、子類代碼塊、子類構造器。

由測試2可知,靜態域只初始化一次。

由測試3可知,只調用靜態域時,只初始化靜態域,和對象無關,靜態域只由類決定。

若父類沒有無參構造器,則必須用super顯式調用父類構造器,不然會報錯。

 可變參數列表

package com.yq;

public class Pig {
    static void test(String... args) {
        for (String str : args)
            System.out.print(str + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        test("小明", "小紅", "小軍", "小華");
    }
}

//輸出
小明 小紅 小軍 小華

其實可變參數列表,是編譯器自動填充了數組。

五、訪問控制許可權

  public、protected、包訪問許可權(沒有關鍵字,預設許可權)、private

  對於類來說,如果一個java文件,存在public類,則java文件名必須和類型一致,而且這個文件只能存在一個public類,若整個文件都不存在public類,則java文件名和類名沒有關係。

  對於成員屬性和方法來說,

  public是最大許可權,任何類都可以訪問。

  protected,繼承訪問許可權,在該類的繼承類中可以訪問,同一個包下可以訪問。

  包訪問許可權,當沒有指明許可權時,預設是包訪問許可權,只有在同一個包下的類才能訪問。

  private是最小的許可權修飾符,只能在本類中訪問。

六、復用類。

  組合:在新的類中放置任意對象,一般是private修飾該對象

  繼承:在新的類中隱式的放置父級對象。

  組合技術通常用於想在新類中使用現有類的功能,而非他的介面。

  繼承技術通常用於保持現有類的形式,並可以添加新代碼。

  一般來說判斷是否使用繼承,問一問自己是否需要從新類像父類進行向上轉型,如果需要則繼承是必須的,否則考慮組合技術應該更合適。

七、多態

  因為多態的存在,程式有了可擴展性。

package com.yq;

class Animal {
    public void eat(String args) {
        System.out.println("Animal eat():" + args);
    }
}

class Pig extends Animal {
    public void eat(String args) {
        System.out.println("Pig eat():" + args);
    }
}

class Cat extends Animal {
    public void eat(String args) {
        System.out.println("Cat eat():" + args);
    }
}

public class Test {

    public static void action(Animal anl) {
        anl.eat("蘋果");
    }

    public static void main(String[] args) {
        Pig pg = new Pig();
        Cat ct = new Cat();
        action(pg);
        action(ct);
    }
}

//輸出
Pig eat():蘋果
Cat eat():蘋果

如果程式中,需要新加動物種類,則只需定義這個類,繼承Animal類即可,主程式不用做任何修改。

那麼為什麼編譯器能這麼智能的找到對應的子類對象,並且正確的調用方法呢?

原因就是:方法後期綁定,也叫作動態綁定。

意思是,在運行時根據對象的類型進行綁定,而不是在定義方法就進行前期綁定。

java中除了static和final方法(private方法也屬於final方法,因為final是隱式申明的)之外,其他所有的方法都是後期綁定。

八、抽象類和介面

  包含抽象方法的類叫抽象類。

  介面定義了方法的方法名,參數列表和返回類型,可以顯式的申明為public的,也可以不申明,因為預設就是public許可權,另外介面中的成員屬性,也是有域的,預設是final、static的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 舉例 我們先從示例應用程式的一些摘錄開始。下麵是暴露Person對象的響應信息庫。很類似於傳統的,非響應信息庫,只不過它返回Flux<Person>而傳統的返回List<Person>,以及返回Mono<Person>的地方返回Person。Mono<Void>用作完成標識:指出何時保存被完成。關於 ...
  • 今天我們一起來學習WebService。它到底是幹啥用的? Web service是一個平臺獨立的,低耦合的,自包含的、基於可編程的web的應用程式,可使用開放的XML(標準通用標記語言下的一個子集)標準來描述、發佈、發現、協調和配置這些應用程式,用於開發分散式的互操作的應用程式。 一:Web Se ...
  • |定義|含義| | | | |int i|定義整形變數i| |int p|p為指向整形數據類型的指針變數| |int a[n]|定義有n個元素的整型數組a| |int p[n]|定義由n個指向整型數據的指針元素組成的指針數組p| |int ( p)[n]|p為指向n個元素的一維數組的指針變數| |i ...
  • php的閉包可能不常用,但是在某些場合之下還是可以考慮用php的閉包來實現某些功能的,比如遞歸,這裡講一下用php的閉包實現遞歸 這是一個簡單的使用php閉包實現遞歸的函數,其實,假如我們對這個函數稍微修改一下,是可以實現很多功能的,比如說,無限極分類。 關於裡面的閉包函數,其實,我們也可以不用引用 ...
  • List Set 都是介面,都繼承了Collection介面 ArrayList LinkList 直接實現了List介面 HashSet 實現了Set介面 HashSet 實現了Set介面 TreeSet繼承父類AbstractSet 間接的實現了Set 介面 Map 是介面,沒有實現Collec ...
  • JMS是一個用於提供消息服務的技術規範,它制定了在整個消息服務提供過程中的所有數據結構和交互流程。 而activemq則是消息隊列服務,是面向消息中間件(MOM)的最終實現,是真正的服務提供者。 jms 的一個標準或者說是一個協議。 通常用於企業級應用的消息傳遞。 主要有topic 消息(1 對多) ...
  • 一、前言 在之前的隨筆之中,我們已經瞭解Java通過上傳組件來實現上傳和下載,這次我們來瞭解Struts2的上傳和下載。 註意:文件上傳時,我們需要將表單提交方式設置為"POST"方式,並且將enctype屬性設置為"multipart/form-data",該屬性的預設值為"application ...
  • iText是著名的開放項目,是用於生成PDF文檔的一個java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉化為PDF文件。 官方網站:http://itextpdf.com/ 示例版本:itextpdf-5.2.1.jar 示例代碼 document.add ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...