1. 程式人生 > >從零開始學Java——基礎篇

從零開始學Java——基礎篇

整理自菜鳥教程

 


Java 簡介

Java是Java面向物件程式設計語言和Java平臺的總稱。

Java分為三個體系:

  • JavaSE(J2SE)(Java2 Platform Standard Edition,java平臺標準版)
  • JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平臺企業版)
  • JavaME(J2ME)(Java 2 Platform Micro Edition,java平臺微型版)。

主要特性

  • Java語言是簡單的:

    Java語言的語法與C語言和C++語言很接近,使得大多數程式設計師很容易學習和使用。另一方面,Java丟棄了C++中很少使用的、很難理解的、令人迷惑的那些特性,如操作符過載、多繼承、自動的強制型別轉換。特別地,Java語言不使用指標,而是引用。並提供了自動的廢料收集,使得程式設計師不必為記憶體管理而擔憂。

  • Java語言是面向物件的:

    Java語言提供類、介面和繼承等面向物件的特性,為了簡單起見,只支援類之間的單繼承,但支援介面之間的多繼承,並支援類與介面之間的實現機制(關鍵字為implements)。Java語言全面支援動態繫結,而C++語言只對虛擬函式使用動態繫結。總之,Java語言是一個純的面向物件程式設計語言。

  • Java語言是分散式的:

    Java語言支援Internet應用的開發,在基本的Java應用程式設計介面中有一個網路應用程式設計介面(java net),它提供了用於網路應用程式設計的類庫,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(遠端方法啟用)機制也是開發分散式應用的重要手段。

  • Java語言是健壯的:

    Java的強型別機制、異常處理、垃圾的自動收集等是Java程式健壯性的重要保證。對指標的丟棄是Java的明智選擇。Java的安全檢查機制使得Java更具健壯性。

  • Java語言是安全的:

    Java通常被用在網路環境中,為此,Java提供了一個安全機制以防惡意程式碼的攻擊。除了Java語言具有的許多安全特性以外,Java對通過網路下載的類具有一個安全防範機制(類ClassLoader),如分配不同的名字空間以防替代本地的同名類、位元組程式碼檢查,並提供安全管理機制(類SecurityManager)讓Java應用設定安全哨兵。

  • Java語言是體系結構中立的:

    Java程式(字尾為java的檔案)在Java平臺上被編譯為體系結構中立的位元組碼格式(字尾為class的檔案),然後可以在實現這個Java平臺的任何系統中執行。這種途徑適合於異構的網路環境和軟體的分發。

  • Java語言是可移植的:

    這種可移植性來源於體系結構中立性,另外,Java還嚴格規定了各個基本資料型別的長度。Java系統本身也具有很強的可移植性,Java編譯器是用Java實現的,Java的執行環境是用ANSI C實現的。

  • Java語言是解釋型的:

    如前所述,Java程式在Java平臺上被編譯為位元組碼格式,然後可以在實現這個Java平臺的任何系統中執行。在執行時,Java平臺中的Java直譯器對這些位元組碼進行解釋執行,執行過程中需要的類在聯接階段被載入到執行環境中。

  • Java是高效能的:

    與那些解釋型的高階指令碼語言相比,Java的確是高效能的。事實上,Java的執行速度隨著JIT(Just-In-Time)編譯器技術的發展越來越接近於C++。

  • Java語言是多執行緒的:

    在Java語言中,執行緒是一種特殊的物件,它必須由Thread類或其子(孫)類來建立。通常有兩種方法來建立執行緒:其一,使用型構為Thread(Runnable)的構造子將一個實現了Runnable介面的物件包裝成一個執行緒,其二,從Thread類派生出子類並重寫run方法,使用該子類建立的物件即為執行緒。值得注意的是Thread類已經實現了Runnable介面,因此,任何一個執行緒均有它的run方法,而run方法中包含了執行緒所要執行的程式碼。執行緒的活動由一組方法來控制。Java語言支援多個執行緒的同時執行,並提供多執行緒之間的同步機制(關鍵字為synchronized)。

  • Java語言是動態的:

    Java語言的設計目標之一是適應於動態變化的環境。Java程式需要的類能夠動態地被載入到執行環境,也可以通過網路來載入所需要的類。這也有利於軟體的升級。另外,Java中的類有一個執行時刻的表示,能進行執行時刻的型別檢查。


 

Java開發環境的配置

下載適合你的系統的java 開發工具包JDK

安裝

配置環境變數

開發工具建議使用IDE eclipse


Java 基礎語法

一個Java程式可以認為是一系列物件的集合,而這些物件通過呼叫彼此的方法來協同工作。

下面簡要介紹下類、物件、方法和例項變數的概念。

  • 物件:物件是類的一個例項,有狀態和行為。例如,一條狗是一個物件,它的狀態有:顏色、名字、品種;行為有:搖尾巴、叫、吃等。
  • :類是一個模板,它描述一類物件的行為和狀態。
  • 方法:方法就是行為,一個類可以有很多方法。邏輯運算、資料修改以及所有動作都是在方法中完成的。
  • 例項變數:每個物件都有獨特的例項變數,物件的狀態由這些例項變數的值決定。

第一個Java程式

下面看一個簡單的Java程式,它將列印字串 Hello World

例項

public class HelloWorld {
    /* 第一個Java程式
     * 它將列印字串 Hello World
     */
    public static void main(String []args) {
        System.out.println("Hello World"); // 列印 Hello World
    }
}
 

下面將逐步介紹如何儲存、編譯以及執行這個程式:

  • 開啟Notepad,把上面的程式碼新增進去;
  • 把檔名儲存為:HelloWorld.java;
  • 開啟cmd命令視窗,進入目標檔案所在的位置,假設是C:\
  • 在命令列視窗鍵入 javac HelloWorld.java  按下enter鍵編譯程式碼。如果程式碼沒有錯誤,cmd命令提示符會進入下一行。(假設環境變數都設定好了)。
  • 再鍵入java HelloWorld 按下Enter鍵就可以執行程式了

你將會在視窗看到 Hello World

C : > javac HelloWorld.java
C : > java HelloWorld 
Hello World

 

基本語法

編寫Java程式時,應注意以下幾點:

  • 大小寫敏感:Java是大小寫敏感的,這就意味著識別符號Hello與hello是不同的。
  • 類名:對於所有的類來說,類名的首字母應該大寫。如果類名由若干單片語成,那麼每個單詞的首字母應該大寫,例如 MyFirstJavaClass 。
  • 方法名:所有的方法名都應該以小寫字母開頭。如果方法名含有若干單詞,則後面的每個單詞首字母大寫。
  • 原始檔名:原始檔名必須和類名相同。當儲存檔案的時候,你應該使用類名作為檔名儲存(切記Java是大小寫敏感的),檔名的字尾為.java。(如果檔名和類名不相同則會導致編譯錯誤)。
  • 主方法入口:所有的Java 程式由public static void main(String []args)方法開始執行。

Java識別符號

Java所有的組成部分都需要名字。類名、變數名以及方法名都被稱為識別符號。

關於Java識別符號,有以下幾點需要注意:

  • 所有的識別符號都應該以字母(A-Z或者a-z),美元符($)、或者下劃線(_)開始
  • 首字元之後可以是字母(A-Z或者a-z),美元符($)、下劃線(_)或數字的任何字元組合
  • 關鍵字不能用作識別符號
  • 識別符號是大小寫敏感的
  • 合法識別符號舉例:age、$salary、_value、__1_value
  • 非法識別符號舉例:123abc、-salary

Java修飾符

像其他語言一樣,Java可以使用修飾符來修飾類中方法和屬性。主要有兩類修飾符:

  • 訪問控制修飾符 : default, public , protected, private
  • 非訪問控制修飾符 : final, abstract, static, synchronized

Java變數

Java中主要有如下幾種型別的變數

  • 區域性變數
  • 類變數(靜態變數)
  • 成員變數(非靜態變數)

Java陣列

陣列是儲存在堆上的物件,可以儲存多個同類型變數。


Java列舉

Java 5.0引入了列舉,列舉限制變數只能是預先設定好的值。使用列舉可以減少程式碼中的bug。

例如,我們為果汁店設計一個程式,它將限制果汁為小杯、中杯、大杯。這就意味著它不允許顧客點除了這三種尺寸外的果汁。

class FreshJuice {

   enum FreshJuiceSize{ SMALL, MEDIUM , LARGE }

   FreshJuiceSize size;

}

public class FreshJuiceTest {

   public static void main(String []args){

      FreshJuice juice = new FreshJuice();

      juice.size = FreshJuice.FreshJuiceSize.MEDIUM  ;

   }

}

注意:列舉可以單獨宣告或者宣告在類裡面。方法、變數、建構函式也可以在列舉中定義。


Java 關鍵字

下面列出了Java 關鍵字。這些保留字不能用於常量、變數、和任何識別符號的名稱。

類別 關鍵字 說明
訪問控制 private 私有的
protected 受保護的
public 公共的
類、方法和變數修飾符 abstract 宣告抽象
class
extends 擴充,繼承
final 最終值,不可改變的
implements 實現(介面)
interface 介面
native 本地,原生方法(非Java實現)
new 新,建立
static 靜態
strictfp 嚴格,精準
synchronized 執行緒,同步
transient 短暫
volatile 易失
程式控制語句 break 跳出迴圈
case 定義一個值以供switch選擇
continue 繼續
default 預設
do 執行
else 否則
for 迴圈
if 如果
instanceof 例項
return 返回
switch 根據值選擇執行
while 迴圈
錯誤處理 assert 斷言表示式是否為真
catch 捕捉異常
finally 有沒有異常都執行
throw 丟擲一個異常物件
throws 宣告一個異常可能被丟擲
try 捕獲異常
包相關 import 引入
package
基本型別 boolean 布林型
byte 位元組型
char 字元型
double 雙精度浮點
float 單精度浮點
int 整型
long 長整型
short 短整型
變數引用 super 父類,超類
this 本類
void 無返回值
保留關鍵字 goto 是關鍵字,但不能使用
const 是關鍵字,但不能使用
null

Java註釋

類似於C/C++,Java也支援單行以及多行註釋。註釋中的字元將被Java編譯器忽略。

public class HelloWorld {

   /* 這是第一個Java程式

    *它將列印Hello World

    * 這是一個多行註釋的示例

    */

    public static void main(String []args){

       // 這是單行註釋的示例

       /* 這個也是單行註釋的示例 */

       System.out.println("Hello World");

    }

}

Java 空行

空白行,或者有註釋的行,Java編譯器都會忽略掉。


繼承

在Java中,一個類可以由其他類派生。如果你要建立一個類,而且已經存在一個類具有你所需要的屬性或方法,那麼你可以將新建立的類繼承該類。

利用繼承的方法,可以重用已存在類的方法和屬性,而不用重寫這些程式碼。被繼承的類稱為超類(super class),派生類稱為子類(subclass)。


介面

在Java中,介面可理解為物件間相互通訊的協議。介面在繼承中扮演著很重要的角色。

介面只定義派生要用到的方法,但是方法的具體實現完全取決於派生類。


Java 源程式與編譯型執行區別

如下圖所示:


Java 物件和類

Java作為一種面嚮物件語言。支援以下基本概念:

  • 多型
  • 繼承
  • 封裝
  • 抽象
  • 物件
  • 例項
  • 方法
  • 過載

本節我們重點研究物件和類的概念。

  • 物件:物件是類的一個例項,有狀態和行為。例如,一條狗是一個物件,它的狀態有:顏色、名字、品種;行為有:搖尾巴、叫、吃等。
  • :類是一個模板,它描述一類物件的行為和狀態。

Java中的物件

 

現在讓我們深入瞭解什麼是物件。看看周圍真實的世界,會發現身邊有很多物件,車,狗,人等等。所有這些物件都有自己的狀態和行為。

拿一條狗來舉例,它的狀態有:名字、品種、顏色,行為有:叫、搖尾巴和跑。

對比現實物件和軟體物件,它們之間十分相似。

軟體物件也有狀態和行為。軟體物件的狀態就是屬性,行為通過方法體現。

在軟體開發中,方法操作物件內部狀態的改變,物件的相互呼叫也是通過方法來完成。

Java中的類

類可以看成是建立Java物件的模板。

通過下面一個簡單的類來理解下Java中類的定義:

public class Dog

{

   //屬性

    String breed;

    int age;

    String color;

    //方法

    void barking(){ }

    void hungry(){ } 

    void sleeping(){ }

}

一個類可以包含以下型別變數:

  • 區域性變數:在方法、構造方法或者語句塊中定義的變數被稱為區域性變數。變數宣告和初始化都是在方法中,方法結束後,變數就會自動銷燬。
  • 成員變數:成員變數是定義在類中,方法體之外的變數。這種變數在建立物件的時候例項化。成員變數可以被類中方法、構造方法和特定類的語句塊訪問。
  • 類變數:類變數也宣告在類中,方法體之外,但必須宣告為static型別。

一個類可以擁有多個方法,在上面的例子中:barking()、hungry()和sleeping()都是Dog類的方法。


構造方法

每個類都有構造方法。如果沒有顯式地為類定義構造方法,Java編譯器將會為該類提供一個預設構造方法。

在建立一個物件的時候,至少要呼叫一個構造方法。構造方法的名稱必須與類同名,一個類可以有多個構造方法。

下面是一個構造方法示例:

public class Puppy{

    //無引數構造方法和有引數構造方法

    public Puppy(){ }

    public Puppy(String name){ // 這個構造器僅有一個引數:name }

}


建立物件

物件是根據類建立的。在Java中,使用關鍵字new來建立一個新的物件。建立物件需要以下三步:

  • 宣告:宣告一個物件,包括物件名稱和物件型別。
  • 例項化:使用關鍵字new來建立一個物件。
  • 初始化:使用new建立物件時,會呼叫構造方法初始化物件。

下面是一個建立物件的例子:

public class Puppy{

    public Puppy(String name)

    {

    //這個構造器僅有一個引數:name

    System.out.println("小狗的名字是 : " + name );

    }

    public static void main(String []args)

    {

    // 下面的語句將建立一個Puppy物件

     Puppy myPuppy = new Puppy( "tommy" );

    } 

}

編譯並執行上面的程式,會打印出下面的結果:

小狗的名字是 : tommy

訪問例項變數和方法

通過已建立的物件來訪問成員變數和成員方法,如下所示:

/* 例項化物件 */

ObjectReference = new Constructor();

/* 訪問類中的變數 */

ObjectReference.variableName;

/* 訪問類中的方法 */

ObjectReference.methodName();


例項

下面的例子展示如何訪問例項變數和呼叫成員方法:

public class Puppy{

    int puppyAge;

    public Puppy(String name)

    {

    // 這個構造器僅有一個引數:name

    System.out.println("小狗的名字是 : " + name );

    }

    public void setAge( int age )

   {

        puppyAge = age;

    }

    public int getAge( )

    {

        System.out.println("小狗的年齡為 : " + puppyAge );

        return puppyAge;

    }

    public static void main(String []args)

    {

        /* 建立物件 */

        Puppy myPuppy = new Puppy( "tommy" );

        /* 通過方法來設定age */

        myPuppy.setAge( 2 );

        /* 呼叫另一個方法獲取age */

        myPuppy.getAge( );

        /*你也可以像下面這樣訪問成員變數 */

        System.out.println("變數值 : " + myPuppy.puppyAge );

    }

}

編譯並執行上面的程式,產生如下結果:

小狗的名字是 : tommy
小狗的年齡為 : 2
變數值 : 2

原始檔宣告規則

在本節的最後部分,我們將學習原始檔的宣告規則。當在一個原始檔中定義多個類,並且還有import語句和package語句時,要特別注意這些規則。

  • 一個原始檔中只能有一個public類
  • 一個原始檔可以有多個非public類
  • 原始檔的名稱應該和public類的類名保持一致。例如:原始檔中public類的類名是Employee,那麼原始檔應該命名為Employee.java。
  • 如果一個類定義在某個包中,那麼package語句應該在原始檔的首行。
  • 如果原始檔包含import語句,那麼應該放在package語句和類定義之間。如果沒有package語句,那麼import語句應該在原始檔中最前面。
  • import語句和package語句對原始檔中定義的所有類都有效。在同一原始檔中,不能給不同的類不同的包宣告。

類有若干種訪問級別,並且類也分不同的型別:抽象類和final類等。

除了上面提到的幾種型別,Java還有一些特殊的類,如:內部類、匿名類。


Java包

包主要用來對類和介面進行分類。當開發Java程式時,可能編寫成百上千的類,因此很有必要對類和介面進行分類。

Import語句

在Java中,如果給出一個完整的限定名,包括包名、類名,那麼Java編譯器就可以很容易地定位到原始碼或者類。Import語句就是用來提供一個合理的路徑,使得編譯器可以找到某個類。

例如,下面的命令列將會命令編譯器載入java_installation/java/io路徑下的所有類

import java.io.*;

一個簡單的例子

在該例子中,我們建立兩個類:Employee 和 EmployeeTest

首先開啟文字編輯器,把下面的程式碼貼上進去。注意將檔案儲存為 Employee.java。

Employee類有四個成員變數:name、age、designation和salary。該類顯式聲明瞭一個構造方法,該方法只有一個引數。

Employee.java 檔案程式碼:

import java.io.*;

 

public class Employee{

   String name;

   int age;

   String designation;

   double salary;

   // Employee 類的構造器

   public Employee(String name){

      this.name = name;

   }

   // 設定age的值

   public void empAge(int empAge){

      age =  empAge;

   }

   /* 設定designation的值*/

   public void empDesignation(String empDesig){

      designation = empDesig;

   }

   /* 設定salary的值*/

   public void empSalary(double empSalary){

      salary = empSalary;

   }

   /* 列印資訊 */

   public void printEmployee(){

      System.out.println("名字:"+ name );

      System.out.println("年齡:" + age );

      System.out.println("職位:" + designation );

      System.out.println("薪水:" + salary);

   }

}

程式都是從main方法開始執行。為了能執行這個程式,必須包含main方法並且建立一個例項物件。

下面給出EmployeeTest類,該類例項化2個 Employee 類的例項,並呼叫方法設定變數的值。

將下面的程式碼儲存在 EmployeeTest.java檔案中。

EmployeeTest.java 檔案程式碼:

import java.io.*;

public class EmployeeTest{

 

   public static void main(String []args){

      /* 使用構造器建立兩個物件 */

      Employee empOne = new Employee("RUNOOB1");

      Employee empTwo = new Employee("RUNOOB2");

 

      // 呼叫這兩個物件的成員方法

      empOne.empAge(26);

      empOne.empDesignation("高階程式設計師");

      empOne.empSalary(1000);

      empOne.printEmployee();

 

      empTwo.empAge(21);

      empTwo.empDesignation("菜鳥程式設計師");

      empTwo.empSalary(500);

      empTwo.printEmployee();

   }

}

編譯這兩個檔案並且執行 EmployeeTest 類,可以看到如下結果:

$ javac EmployeeTest.java
$ java EmployeeTest 
名字:RUNOOB1
年齡:26
職位:高階程式設計師
薪水:1000.0
名字:RUNOOB2
年齡:21
職位:菜鳥程式設計師
薪水:500.0

 


Java 基本資料型別

變數就是申請記憶體來儲存值。也就是說,當建立變數的時候,需要在記憶體中申請空間。

記憶體管理系統根據變數的型別為變數分配儲存空間,分配的空間只能用來儲存該型別資料。

因此,通過定義不同型別的變數,可以在記憶體中儲存整數、小數或者字元。

Java 的兩大資料型別:

  • 內建資料型別
  • 引用資料型別

內建資料型別

Java語言提供了八種基本型別。六種數字型別(四個整數型,兩個浮點型),一種字元型別,還有一種布林型。

byte:

  • byte 資料型別是8位、有符號的,以二進位制補碼錶示的整數;
  • 最小值是 -128(-2^7);
  • 最大值是 127(2^7-1);
  • 預設值是 0;
  • byte 型別用在大型陣列中節約空間,主要代替整數,因為 byte 變數佔用的空間只有 int 型別的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short 資料型別是 16 位、有符號的以二進位制補碼錶示的整數
  • 最小值是 -32768(-2^15);
  • 最大值是 32767(2^15 - 1);
  • Short 資料型別也可以像 byte 那樣節省空間。一個short變數是int型變數所佔空間的二分之一;
  • 預設值是 0;
  • 例子:short s = 1000,short r = -20000。

int:

  • int 資料型別是32位、有符號的以二進位制補碼錶示的整數;
  • 最小值是 -2,147,483,648(-2^31);
  • 最大值是 2,147,483,647(2^31 - 1);
  • 一般地整型變數預設為 int 型別;
  • 預設值是 0 ;
  • 例子:int a = 100000, int b = -200000。

long:

  • long 資料型別是 64 位、有符號的以二進位制補碼錶示的整數;
  • 最小值是 -9,223,372,036,854,775,808(-2^63);
  • 最大值是 9,223,372,036,854,775,807(2^63 -1);
  • 這種型別主要使用在需要比較大整數的系統上;
  • 預設值是 0L;
  • 例子: long a = 100000L,Long b = -200000L。
    "L"理論上不分大小寫,但是若寫成"l"容易與數字"1"混淆,不容易分辯。所以最好大寫。

float:

  • float 資料型別是單精度、32位、符合IEEE 754標準的浮點數;
  • float 在儲存大型浮點陣列的時候可節省記憶體空間;
  • 預設值是 0.0f;
  • 浮點數不能用來表示精確的值,如貨幣;
  • 例子:float f1 = 234.5f。

double:

  • double 資料型別是雙精度、64 位、符合IEEE 754標準的浮點數;
  • 浮點數的預設型別為double型別;
  • double型別同樣不能表示精確的值,如貨幣;
  • 預設值是 0.0d;
  • 例子:double d1 = 123.4。

boolean:

  • boolean資料型別表示一位的資訊;
  • 只有兩個取值:true 和 false;
  • 這種型別只作為一種標誌來記錄 true/false 情況;
  • 預設值是 false;
  • 例子:boolean one = true。

char:

  • char型別是一個單一的 16 位 Unicode 字元;
  • 最小值是 \u0000(即為0);
  • 最大值是 \uffff(即為65,535);
  • char 資料型別可以儲存任何字元;
  • 例子:char letter = 'A';。

 

對於數值型別的基本型別的取值範圍,我們無需強制去記憶,因為它們的值都已經以常量的形式定義在對應的包裝類中了。

包裝類:java.lang.Byte

包裝類:java.lang.Short 

包裝類:java.lang.Integer

包裝類:java.lang.Long

包裝類:java.lang.Float

包裝類:java.lang.Double

包裝類:java.lang.Character

Float和Double的最小值和最大值都是以科學記數法的形式輸出的,結尾的"E+數字"表示E之前的數字要乘以10的多少次方。比如3.14E3就是3.14 × 103 =3140,3.14E-3 就是 3.14 x 10-3 =0.00314。

實際上,JAVA中還存在另外一種基本型別void,它也有對應的包裝類 java.lang.Void,不過我們無法直接對它們進行操作。


引用型別

  • 在Java中,引用型別的變數非常類似於C/C++的指標。引用型別指向一個物件,指向物件的變數是引用變數。這些變數在宣告時被指定為一個特定的型別,比如 Employee、Puppy 等。變數一旦聲明後,型別就不能被改變了。
  • 物件、陣列都是引用資料型別。
  • 所有引用型別的預設值都是null。
  • 一個引用變數可以用來引用任何與之相容的型別。
  • 例子:Site site = new Site("Runoob")。

Java 常量

常量在程式執行時是不能被修改的。

在 Java 中使用 final 關鍵字來修飾常量,宣告方式和變數類似:

final double PI = 3.1415927;

雖然常量名也可以用小寫,但為了便於識別,通常使用大寫字母表示常量。

字面量可以賦給任何內建型別的變數。例如:

byte a = 68;
char a = 'A'

byte、int、long、和short都可以用十進位制、16進位制以及8進位制的方式來表示。

當使用常量的時候,字首 0 表示 8 進位制,而字首 0x 代表 16 進位制, 例如:

int decimal = 100;
int octal = 0144;
int hexa =  0x64;

和其他語言一樣,Java的字串常量也是包含在兩個引號之間的字元序列。下面是字串型字面量的例子:

"Hello World"
"two\nlines"
"\"This is in quotes\""

字串常量和字元常量都可以包含任何Unicode字元。例如:

char a = '\u0001';
String a = "\u0001";

Java語言支援一些特殊的轉義字元序列。

符號 字元含義
\n 換行 (0x0a)
\r 回車 (0x0d)
\f 換頁符(0x0c)
\b 退格 (0x08)
\0 空字元 (0x20)
\s 字串
\t 製表符
\" 雙引號
\' 單引號
\\ 反斜槓
\ddd 八進位制字元 (ddd)
\uxxxx 16進位制Unicode字元 (xxxx)

自動型別轉換

整型、實型(常量)、字元型資料可以混合運算。運算中,不同型別的資料先轉化為同一型別,然後進行運算。

轉換從低階到高階。

低  ------------------------------------>  高

byte,short,char—> int —> long—> float —> double 

資料型別轉換必須滿足如下規則:

  • 1. 不能對boolean型別進行型別轉換。

  • 2. 不能把物件型別轉換成不相關類的物件。

  • 3. 在把容量大的型別轉換為容量小的型別時必須使用強制型別轉換。

  • 4. 轉換過程中可能導致溢位或損失精度,例如:

    int i =128;   
    byte b = (byte)i;

    因為 byte 型別是 8 位,最大值為127,所以當 int 強制轉換為 byte 型別時,值 128 時候就會導致溢位。

  • 5. 浮點數到整數的轉換是通過捨棄小數得到,而不是四捨五入,例如:

    (int)23.7 == 23;        
    (int)-45.89f == -45

自動型別轉換

必須滿足轉換前的資料型別的位數要低於轉換後的資料型別,例如: short資料型別的位數為16位,就可以自動轉換位數為32的int型別,同樣float資料型別的位數為32,可以自動轉換為64位的double型別。

例項

public class ZiDongLeiZhuan

{

public static void main(String[] args)

{

    char c1='a';//定義一個char型別

    int i1 = c1;//char自動型別轉換為int

    System.out.println("char自動型別轉換為int後的值等於"+i1);

    char c2 = 'A';//定義一個char型別

    int i2 = c2+1;//char 型別和 int 型別計算

    System.out.println("char型別和int計算後的值等於"+i2);

}

}

執行結果為:

char自動型別轉換為int後的值等於97
char型別和int計算後的值等於66

解析:c1 的值為字元 a ,查 ASCII 碼錶可知對應的 int 型別值為 97, A 對應值為 65,所以 i2=65+1=66。

強制型別轉換

1. 條件是轉換的資料型別必須是相容的。

2. 格式:(type)value type是要強制型別轉換後的資料型別 

例項

public class QiangZhiZhuanHuan

{

public static void main(String[] args)

{

     int i1 = 123; byte b = (byte)i1;//強制型別轉換為byte

    System.out.println("int強制型別轉換為byte後的值等於"+b);

}

}

執行結果:

int強制型別轉換為byte後的值等於123

隱含強制型別轉換

  • 1. 整數的預設型別是 int。

  • 2. 浮點型不存在這種情況,因為在定義 float 型別時必須在數字後面跟上 F 或者 f。

 


 

Java 變數型別

在Java語言中,所有的變數在使用前必須宣告。宣告變數的基本格式如下:

type identifier [ = value][, identifier [= value] ...] ;

格式說明:type為Java資料型別。identifier是變數名。可以使用逗號隔開來宣告多個同類型變數。

 

以下列出了一些變數的宣告例項。注意有些包含了初始化過程。

int a, b, c;         // 宣告三個int型整數:a、 b、c

int d = 3, e = 4, f = 5; // 宣告三個整數並賦予初值

byte z = 22;         // 宣告並初始化 z

String s = "runoob"; // 宣告並初始化字串 s

double pi = 3.14159; // 聲明瞭雙精度浮點型變數 pi

char x = 'x';        // 宣告變數 x 的值是字元 'x'。

Java語言支援的變數型別有:

  • 類變數:獨立於方法之外的變數,用 static 修飾。
  • 例項變數:獨立於方法之外的變數,不過沒有 static 修飾。
  • 區域性變數:類的方法中的變數。

例項

public class Variable

{

static int allClicks=0; // 類變數

String str="hello world"; // 例項變數

public void method()

{

    int i =0; // 區域性變數

}

}


Java 區域性變數

  • 區域性變數宣告在方法、構造方法或者語句塊中;
  • 區域性變數在方法、構造方法、或者語句塊被執行的時候建立,當它們執行完成後,變數將會被銷燬;
  • 訪問修飾符不能用於區域性變數;
  • 區域性變數只在宣告它的方法、構造方法或者語句塊中可見;
  • 區域性變數是在棧上分配的。
  • 區域性變數沒有預設值,所以區域性變數被聲明後,必須經過初始化,才可以使用。

例項 1

在以下例項中age是一個區域性變數。定義在pupAge()方法中,它的作用域就限制在這個方法中。

package com.runoob.test;

public class Test{

public void pupAge()

{

    int age = 0;

    age = age + 7;

    System.out.println("小狗的年齡是: " + age);

}

public static void main(String[] args)

{

    Test test = new Test();

    test.pupAge();

}

}

以上例項編譯執行結果如下:

小狗的年齡是: 7

例項 2

在下面的例子中 age 變數沒有初始化,所以在編譯時會出錯:

package com.runoob.test;

public class Test

{

public void pupAge()

{

    int age;

    age = age + 7;

    System.out.println("小狗的年齡是 : " + age);

}

public static void main(String[] args)

{

    Test test = new Test();

    test.pupAge();

}

}

以上例項編譯執行結果如下:

Test.java:4:variable number might not have been initialized
age = age + 7;
         ^
1 error

例項變數

  • 例項變數宣告在一個類中,但在方法、構造方法和語句塊之外;
  • 當一個物件被例項化之後,每個例項變數的值就跟著確定;
  • 例項變數在物件建立的時候建立,在物件被銷燬的時候銷燬;
  • 例項變數的值應該至少被一個方法、構造方法或者語句塊引用,使得外部能夠通過這些方式獲取例項變數資訊;
  • 例項變數可以宣告在使用前或者使用後;
  • 訪問修飾符可以修飾例項變數;
  • 例項變數對於類中的方法、構造方法或者語句塊是可見的。一般情況下應該把例項變數設為私有。通過使用訪問修飾符可以使例項變數對子類可見;
  • 例項變數具有預設值。數值型變數的預設值是0,布林型變數的預設值是false,引用型別變數的預設值是null。變數的值可以在宣告時指定,也可以在構造方法中指定;
  • 例項變數可以直接通過變數名訪問。但在靜態方法以及其他類中,就應該使用完全限定名:ObejectReference.VariableName。

例項

Employee.java 檔案程式碼:

import java.io.*;

public class Employee

{

// 這個例項變數對子類可見

public String name;

// 私有變數,僅在該類可見

private double salary;

//在構造器中對name賦值

public Employee (String empName)

{

     name = empName;

}

//設定salary的值

public void setSalary(double empSal)

{

    salary = empSal;

}

// 列印資訊

public void printEmp()

{

    System.out.println("名字 : " + name );

    System.out.println("薪水 : " + salary);

}

public static void main(String[] args)

{

    Employee empOne = new Employee("RUNOOB");

    empOne.setSalary(1000);

    empOne.printEmp();

}

}

以上例項編譯執行結果如下:

$ javac Employee.java 
$ java Employee
名字 : RUNOOB
薪水 : 1000.0

類變數(靜態變數)

  • 類變數也稱為靜態變數,在類中以static關鍵字宣告,但必須在方法構造方法和語句塊之外。
  • 無論一個類建立了多少個物件,類只擁有類變數的一份拷貝。
  • 靜態變數除了被宣告為常量外很少使用。常量是指宣告為public/private,final和static型別的變數。常量初始化後不可改變。
  • 靜態變數儲存在靜態儲存區。經常被宣告為常量,很少單獨使用static宣告變數。
  • 靜態變數在第一次被訪問時建立,在程式結束時銷燬。
  • 與例項變數具有相似的可見性。但為了對類的使用者可見,大多數靜態變數宣告為public型別。
  • 預設值和例項變數相似。數值型變數預設值是0,布林型預設值是false,引用型別預設值是null。變數的值可以在宣告的時候指定,也可以在構造方法中指定。此外,靜態變數還可以在靜態語句塊中初始化。
  • 靜態變數可以通過:ClassName.VariableName的方式訪問。
  • 類變數被宣告為public static final型別時,類變數名稱一般建議使用大寫字母。如果靜態變數不是public和final型別,其命名方式與例項變數以及區域性變數的命名方式一致。

 


Java 修飾符

Java語言提供了很多修飾符,主要分為以下兩類:

  • 訪問修飾符
  • 非訪問修飾符

修飾符用來定義類、方法或者變數,通常放在語句的最前端。我們通過下面的例子來說明:

public class className { // ... }

private boolean myFlag;

static final double weeks = 9.5;

protected static final int BOXWIDTH = 42;

public static void main(String[] arguments) { // 方法體 }


訪問控制修飾符

Java中,可以使用訪問控制符來保護對類、變數、方法和構造方法的訪問。Java 支援 4 種不同的訪問許可權。

  • default (即預設,什麼也不寫): 在同一包內可見,不使用任何修飾符。使用物件:類、介面、變數、方法。

  • private : 在同一類內可見。使用物件:變數、方法。 注意:不能修飾類(外部類)

  • public : 對所有類可見。使用物件:類、介面、變數、方法

  • protected : 對同一包內的類和所有子類可見。使用物件:變數、方法。 注意:不能修飾類(外部類)

我們可以通過以下表來說明訪問許可權:

訪問控制
修飾符 當前類 同一包內 子孫類(同一包) 子孫類(不同包) 其他包
public Y Y Y Y Y
protected Y Y Y Y/N(說明 N
default Y Y Y N N
private Y N N N N

預設訪問修飾符-不使用任何關鍵字

使用預設訪問修飾符宣告的變數和方法,對同一個包內的類是可見的。接口裡的變數都隱式宣告為 public static final,而接口裡的方法預設情況下訪問許可權為 public。

如下例所示,變數和方法的宣告可以不使用任何修飾符。

例項

String version = "1.5.1";

boolean processOrder() { return true; }

私有訪問修飾符-private

私有訪問修飾符是最嚴格的訪問級別,所以被宣告為 private 的方法、變數和構造方法只能被所屬類訪問,並且類和介面不能宣告為 private

宣告為私有訪問型別的變數只能通過類中公共的 getter 方法被外部類訪問。

Private 訪問修飾符的使用主要用來隱藏類的實現細節和保護類的資料。

下面的類使用了私有訪問修飾符:

public class Logger

{

private String format;

public String getFormat()

{

    return this.format;

}

public void setFormat(String format)

{

    this.format = format;

}

}

例項中,Logger 類中的 format 變數為私有變數,所以其他類不能直接得到和設定該變數的值。為了使其他類能夠操作該變數,定義了兩個 public 方法:getFormat() (返回 format的值)和 setFormat(String)(設定 format 的值)

公有訪問修飾符-public

被宣告為 public 的類、方法、構造方法和介面能夠被任何其他類訪問。

如果幾個相互訪問的 public 類分佈在不同的包中,則需要匯入相應 public 類所在的包。由於類的繼承性,類所有的公有方法和變數都能被其子類繼承。

以下函式使用了公有訪問控制:

public static void main(String[] arguments) { // ... }

Java 程式的 main() 方法必須設定成公有的,否則,Java 直譯器將不能執行該類。

受保護的訪問修飾符-protected

protected 需要從以下兩個點來分析說明:

  • 子類與基類在同一包中:被宣告為 protected 的變數、方法和構造器能被同一個包中的任何其他類訪問;

  • 子類與基類不在同一包中:那麼在子類中,子類例項可以訪問其從基類繼承而來的 protected 方法,而不能訪問基類例項的protected方法。

protected 可以修飾資料成員,構造方法,方法成員,不能修飾類(內部類除外)

介面及介面的成員變數和成員方法不能宣告為 protected。

子類能訪問 protected 修飾符宣告的方法和變數,這樣就能保護不相關的類使用這些方法和變數。

 

訪問控制和繼承

請注意以下方法繼承的規則:

  • 父類中宣告為 public 的方法在子類中也必須為 public。

  • 父類中宣告為 protected 的方法在子類中要麼宣告為 protected,要麼宣告為 public,不能宣告為 private。

  • 父類中宣告為 private 的方法,不能夠被繼承。


非訪問修飾符

為了實現一些其他的功能,Java 也提供了許多非訪問修飾符。

static 修飾符,用來修飾類方法和類變數。

final 修飾符,用來修飾類、方法和變數,final 修飾的類不能夠被繼承,修飾的方法不能被繼承類重新定義,修飾的變數為常量,是不可修改的。

abstract 修飾符,用來建立抽象類和抽象方法。

synchronized 和 volatile 修飾符,主要用於執行緒的程式設計。

static 修飾符

  • 靜態變數:

    static 關鍵字用來宣告獨立於物件的靜態變數,無論一個類例項化多少物件,它的靜態變數只有一份拷貝。 靜態變數也被稱為類變數。區域性變數不能被宣告為 static 變數。

  • 靜態方法:

    static 關鍵字用來宣告獨立於物件的靜態方法。靜態方法不能使用類的非靜態變數。靜態方法從引數列表得到資料,然後計算這些資料。

對類變數和方法的訪問可以直接使用 classname.variablename 和 classname.methodname 的方式訪問。

 

final 修飾符

final 變數:

final 表示"最後的、最終的"含義,變數一旦賦值後,不能被重新賦值。被 final 修飾的例項變數必須顯式指定初始值。

final 修飾符通常和 static 修飾符一起使用來建立類常量。

 

final 方法

類中的 final 方法可以被子類繼承,但是不能被子類修改。

宣告 final 方法的主要目的是防止該方法的內容被修改。

 

final 類

final 類不能被繼承,沒有類能夠繼承 final 類的任何特性。

 

abstract 修飾符

抽象類:

抽象類不能用來例項化物件,宣告抽象類的唯一目的是為了將來對該類進行擴充。

一個類不能同時被 abstract 和 final 修飾。如果一個類包含抽象方法,那麼該類一定要宣告為抽象類,否則將出現編譯錯誤。

抽象類可以包含抽象方法和非抽象方法。

 

抽象方法

抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。

抽象方法不能被宣告成 final 和 static。

任何繼承抽象類的子類必須實現父類的所有抽象方法,除非該子類也是抽象類。

如果一個類包含若干個抽象方法,那麼該類必須宣告為抽象類。抽象類可以不包含抽象方法。

抽象方法的宣告以分號結尾,例如:public abstract sample();

 

synchronized 修飾符

synchronized 關鍵字宣告的方法同一時間只能被一個執行緒訪問。synchronized 修飾符可以應用於四個訪問修飾符。

 

transient 修飾符

序列化的物件包含被 transient 修飾的例項變數時,java 虛擬機器(JVM)跳過該特定的變數。

該修飾符包含在定義變數的語句中,用來預處理類和變數的資料型別。

例項

public transient int limit = 55; // 不會持久化

public int b; // 持久化

 

volatile 修飾符

volatile 修飾的成員變數在每次被執行緒訪問時,都強制從共享記憶體中重新讀取該成員變數的值。而且,當成員變數發生變化時,會強制執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。

一個 volatile 物件引用可能是 null。

例項

public class MyRunnable implements Runnable

{

private volatile boolean active;

public void run()

{

    active = true;

    while (active)  { //第一行程式碼 }

}

public void stop()

{

    active = false; // 第二行

}

}

通常情況下,在一個執行緒呼叫 run() 方法(在 Runnable 開啟的執行緒),在另一個執行緒呼叫 stop() 方法。 如果 第一行 中緩衝區的 active 值被使用,那麼在 第二行 的 active 值為 false 時迴圈不會停止。

但是以上程式碼中我們使用了 volatile 修飾 active,所以該迴圈會停止。


Java 運算子

計算機的最基本用途之一就是執行數學運算,作為一門計算機語言,Java也提供了一套豐富的運算子來操縱變數。我們可以把運算子分成以下幾組:

  • 算術運算子
  • 關係運算符
  • 位運算子
  • 邏輯運算子
  • 賦值運算子
  • 其他運算子

算術運算子

算術運算子用在數學表示式中,它們的作用和在數學中的作用一樣。下表列出了所有的算術運算子。

表格中的例項假設整數變數A的值為10,變數B的值為20:

操作符 描述 例子
+ 加法 - 相加運算子兩側的值 A + B 等於 30
- 減法 - 左運算元減去右運算元 A – B 等於 -10
* 乘法 - 相乘操作符兩側的值 A * B等於200
/ 除法 - 左運算元除以右運算元 B / A等於2
取餘 - 左運算元除以右運算元的餘數 B%A等於0
++ 自增: 運算元的值增加1 B++ 或 ++B 等於 21(區別詳見下文)
-- 自減: 運算元的值減少1 B-- 或 --B 等於 19(區別詳見下文)

 

自增自減運算子

1、自增(++)自減(--)運算子是一種特殊的算術運算子,在算術運算子中需要兩個運算元來進行運算,而自增自減運算子是一個運算元。

例項

int a = 3;//定義一個變數;

int b = ++a;//自增運算 b = 4

int c = 3;

int d = --c;//自減運算 c = 2

解析:

  • int b = ++a; 拆分運算過程為: a=a+1=4; b=a=4, 最後結果為b=4,a=4

  • int d = --c; 拆分運算過程為: c=c-1=2; d=c=2, 最後結果為d=2,c=2

2、字首自增自減法(++a,--a): 先進行自增或者自減運算,再進行表示式運算。

 

3、字尾自增自減法(a++,a--): 先進行表示式運算,再進行自增或者自減運算 

例項

public class selfAddMinus{

    public static void main(String[] args){

        int a = 5;//定義一個變數;