程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java語言基礎,java語言

java語言基礎,java語言

編輯:JAVA綜合教程

java語言基礎,java語言


一、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的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved