編者按:
此為Java編程新手系列第三篇,前兩篇分別簡單的介紹了「什麼是Java」以及「主題式推進」學習的基本立足點。主要為構建java編程學習的核心基礎的體系化支撐點,建立從頭開始學習的總體性基礎把握,以知識性為主,適合快速閱覽,以打開通往Java世界的視窗。本篇是面向Java新手第三篇,快速而簡潔描述在Java學習中,這些基礎性的核心要點,要一步步的都趟一遍,構建起夯實的基礎知識面。還有未曾羅列的部分,但每個清單都有相應的關聯知識和外延擴張,這就要根據我所推薦的「最佳圖書」和所提倡的「主題式推進」學習來進一步落實行動了。
本文閱讀方式:以瀏覽內容的標題性文字為主,快速瀏覽相應內容簡介。
前兩篇為編程新手所寫的博文:
編程新手(一):Java認知及初學者指南;
編程新手(二):Java最佳學習——主題式推進。
這篇備忘清單了解完後,可以從這裡開始學習:《Java從入門到實戰(極速版)》
首先,關於Java程式語言,你開始所要的基本認知包括而不限於如下主要方面:
- u 面向對象的程式語言:基於「對象」的概念。
- u 開源:易於開發且穩健。
- u 平台中立:Java 代碼獨立於任何特定的硬體或軟體。這是因為 Java 代碼由編譯器編譯並轉換為字節碼。而字節碼是獨立於平台的,可在多個系統上運行。唯一的要求是 Java 需要一個運行時環境,即 JRE,它是一組用於開發 Java 應用程式的工具。
- u 內存管理:自動垃圾收集的語言,即自行釋放或管理內存。
- u 異常處理:可捕捉一系列錯誤或異常,從而消除系統崩潰的任何風險。
接下來,我將羅列在從頭開始的Java學習中,需要逐步掌握的核心知識點。
1.有關Java 流行說法
Java具有以下主要特性目標
- ü 簡單、小巧、通用
- ü 面向對象
- ü 便攜且獨立於平台
- ü 編譯和解釋
- ü 可擴展性和性能
- ü 穩健且安全
- ü 建築中立
- ü 高性能
- ü 多線程
- ü 分散式
- ü 動態和可擴展
2.Java基本數據類型
數據類型 |
默認值 |
大小(字節:1 byte = 8 bits) |
boolean |
false |
1 bit |
char |
空格」 」 |
2 byte |
byte |
0 |
1 byte |
short |
0 |
2 byte |
int |
0 |
4 byte |
long |
0 |
8 byte |
float |
0.0f |
4 byte |
double |
0.0d |
8 byte |
非基本數據類型
- String 字符串
- Array 數組
- enum 枚舉
- Class 類
- Interface 接口
3.類型轉換
它是一種將一種數據類型的變量轉換為另一種數據類型以正確處理這些變量的方法。
Java 定義了兩種類型的類型轉換:
- ü 隱式類型轉換(寬化):將較小的數據類型存儲為較大的數據類型。
- ü 顯式類型轉換(窄化):將較大數據類型的變量存儲為較小數據類型。
4.Java 中的運算符
Java 支持豐富的運算符集,可分為以下幾類:
運算符分類 |
運算符 |
算術運算符 |
+,-,/,*,% |
關係運算符 |
<, >, <=, >=,==, != |
邏輯運算符 |
&& , || |
賦值運算符 |
=, +=, −=, ×=, ÷=, %=, &=, ^=, |=, <<=, >>=, >>>= |
自增自減運算符 |
++ , - - |
條件運算符(三運算符) |
?: |
位運算符 |
^, &, | |
特殊運算符 |
. (點運算符針對類方法的訪問) |
5.Java IDE 和代碼執行:
在眾多 IDE 中,我最推薦的是(企業級產品性的保障):
- ü Eclipse
- ü NetBeans
Java 代碼也可以在任何文本編輯器中編寫,並使用以下命令在終端上編譯和運行:
$ javac [file_name].java
$ java [file_name]
注意:編譯時,文件名應與包含 main() 方法的類名相同,並帶有 .java 擴展名。
6.Java中的變量
變量是數據在內存位置的名稱。它是在執行 java 程序時保存值的容器。 Java 中的變量分為三種類型:
局部變量 |
全局或實例變量 |
靜態變量 |
在方法、塊或構造函數體中聲明並初始化的。 |
在類內部聲明,但在方法、塊或構造函數之外聲明。如果未初始化,則默認值為0。 |
使用「static」關鍵字聲明。它不可能是局部的。 |
它只能在聲明它的方法中訪問,稍後在塊中或函數調用返回時銷毀。 |
變量在類的實例創建時創建,在實例銷毀時銷毀。 |
創建的變量是為了在類級別的所有對象之間的共享內存中創建單個副本以共享。 |
代碼示例如下:
class TestVariables{
int data = 20; // 實例變量
static int number = 10; //靜態變量
void someMethod(){
int num = 30; //局部變量
}
}
7.保留字
也稱為關鍵字,這些特定的詞是在 Java 中預定義的,不能用作變量或對象名稱。其中重要的關鍵字:
關鍵字 |
用法 |
abstract |
用於聲明一個抽象類。 |
catch |
用於捕獲try語句生成的異常。 |
class |
用於聲明一個類。 |
enum |
定義一組常量 |
extends |
指明該類是繼承的 |
final |
該值不能修改 |
finally |
用於在try-catch結構之後執行代碼。 |
implements |
用於實現接口。 |
new |
用於創建新對象。 |
static |
用於指示變量或類方法。 |
super |
用於引用父類。 |
this |
用於在方法或構造函數中引用當前對象。 |
throw |
用於顯式拋出異常。 |
throws |
用於聲明拋出的異常。 |
try |
處理異常的代碼塊 |
8.Java 中的方法
方法的一般形式:
- ü 類型 - 方法的返回類型
- ü 名稱 - 方法的名稱
- ü 參數列表 - 由逗號分隔的類型和變量的序列
- ü return - 將值返回給調用者語句
示例如下:
type name (parameter list){
//方法體
//return value (僅當type不是void時)
}
9.條件語句
1) if/if-else/if-else if/ if-else if-else
檢測條件,如果條件為true,則執行塊,否則執行 else 塊。示例:
class TestIfElse{
public static void main(String args[]){
int percent = 75;
if(percent >= 75){
System.out.println("Passed");
}else {
System.out.println("Please attempt again!");
}
}
}
只能有一個if塊和一個else塊,else if 是可選的。
2)switch
測試條件;如果特定情況為真,則將控制傳遞給該塊並執行。其餘情況不再考慮,而程序跳出switch塊。示例如下:
class TestSwitch{
public static void main(String args[]){
int weather = 0;
switch(weather){
case 0 :
System.out.println("Sunny");
break;
case 1 :
System.out.println("Rainy");
break;
case 2 :
System.out.println("Cold");
break;
case 3 :
System.out.println("Windy");
break;
default :
System.out.println("Pleasant");
}
}
}
3)Java 中的循環
循環用於將代碼疊代特定次數,直到指定條件為true。 Java中有三種循環:
for 循環:將代碼疊代特定次數,直到條件為真。示例如下: |
class TestForLoop{ public static void main (String args[]){ for(int i=0;i<=5;i++) System.out.println("*"); } } |
while循環:如果一段時間內的條件為真,則程序進入循環疊代。示例如下: |
class TestWhileLoop{ public static void main (String args[]) { int i = 1; while(i<=10) { System.out.println(i); i++; } } } |
do-while循環:無論 while 條件是否為真,程序都會進入循環進行至少一次的疊代。對於進一步的疊代,它取決於 while 條件是否為真。示例如下: |
class TestDoWhileLoop{
public static void main (String args[]) {
int i = 1;
do {
System.out.println(i);
i++;
}while(i<=10);
}
}
10.OOP概念
面向對象範式提供以下概念來簡化軟體開發和維護。
1)對象和類
對象是面向對象系統中的基本運行時實體,它包含數據和操作數據的代碼。可以使用類概念將這整套數據和代碼製成用戶定義的數據類型。因此,類是具有相似數據類型的對象的集合。
示例:apple、mango 和 orange 是水果類的成員。
2) 數據抽象與封裝
將數據和方法包裝或封裝到一個單元中稱為封裝。以藥用膠囊為例;我們不知道它含有什麼化學物質;我們只關心它的效果。
這種將數據與程序直接訪問隔離的過程稱為數據隱藏。例如,在使用應用程式時,人們關心的是它們的功能而不是它們的代碼。
3)繼承
繼承提供了可重用性的概念;它是一個類(子類)的對象如何繼承或派生自另一個類(父類)的對象的屬性。Java 中的繼承類型
- ü 單一繼承:子類從單一父類繼承屬性和行為。
- ü 多級繼承:子類從其父類繼承屬性,而父類又是另一個父類的子類。
- ü 多重繼承:當一個子類有兩個父類時。在 Java 中,這個概念是通過使用接口來實現的。
- ü 分層繼承:當一個父類有兩個子類繼承其屬性時。
示例代碼如下:
class A{
int i, j;
void showij() {
System.out.println("i and j: " + i + " " + j);
}
}
// 通過擴展類A來創建子類B
class B extends A {
int k;
void showk() {
System.out.println("k: " + k);
}
void sum() {
System.out.println("i+j+k: " + (i+j+k));
}
}
class SimpleInheritance {
public static void main(String args[]) {
A objA = new A();
B objB = new B();
// 超類可以單獨使用
objA.i = 10;
objA.j = 20;
System.out.println("Contents of objA: ");
objA.showij();
System.out.println();
/* 子類可以訪問超類/父類所有公共成員。 */
objB.i = 7;
objB.j = 8;
objB.k = 9;
System.out.println("Contents of objB: ");
objB.showij();
objB.showk();
System.out.println();
System.out.println("Sum of i, j and k in objB:");
objB.sum();
}
}
繼承的一些限制:
- ü 子類不能派生超類的私有成員。
- ü 子類不能繼承構造函數。
- ü 一個子類只有一個超類。
4)多態
多態定義為接受多種形式的能力。多態允許創建乾淨可讀的代碼。
在Java多態中,實現了方法重載和方法覆蓋的概念,這就是動態的方法。
4.1)方法覆蓋
在類層次結構中,當子類中的方法與其父類中的方法具有相同的名稱和類型簽名時,則稱子類中的方法覆蓋父類中的方法。
如果我們不重寫下面代碼中的方法,則輸出將是 ParentMath 類中計算的 4;否則,它將是 16。示例如下:
class ParentMath{
void area(){
int a =2;
System.out.printf("Area of Square with side 2 = %d %n", a * a);
System.out.println();
}
}
class ChildMath extends ParentMath{
void area(){
int a =4;
System.out.printf("Area of Square with side 4= %d %n", a * a);
}
public static void main (String args[]){
ChildMath obj = new ChildMath();
obj.area();
}
}
4.2)方法重載
Java 編程可以在同一個類中有兩個或多個共享相同名稱的方法,只要它們的參數聲明不同即可。此類方法稱為重載,過程稱為方法重載。
方法重載的三種方式:
(1)參數個數:
add(int, int)
add(int, int, int)
(2)參數類型:
add(int, int)
add(int, float)
(3)參數數據類型的順序
add(int, float)
add(float, int)
Program to explain multilevel inheritance and method overloading :
多級繼承和方法重載的程序示例如下:
class Shape{
void area() {
System.out.println("Area of the following shapes are : ");
}
}
class Square extends Shape {
void area(int length) {
//計算正方形面積
int area = length * length;
System.out.println("Area of square : "+area);
}
}
class Rectangle extends Shape {
//定義一個寬度
void area(int length,int breadth) {
//calculate area of rectangle
int area = length * breadth;
System.out.println("Area of rectangle : " + area);
}
}
class Circle extends Shape{
void area(int breadth){
//用形狀類的長度作為半徑計算圓的面積
float area = 3.14f * breadth * breadth;
System.out.println("Area of circle : " + area);
}
}
class InheritanceOverload{
public static void main(String[] args){
int length = 5;
int breadth = 7;
Shape s = new Shape();
//子類square對象
Square sq = new Square();
//子類rectangle的對象
Rectangle rec = new Rectangle();
//子類Circle的對象
Circle cir = new Circle();
//調用所有子類的area方法來獲得不同對象的area
s.area();
sq.area(length);
rec.area(length,breadth);
cir.area(length);
}
}
5)抽象類
超類只定義了一個由其所有子類共享的通用形式,將其留給每個子類來實現其方法。
abstract class A {
abstract void callme();
// concrete methods are still allowed in abstract classes
void callmetoo() {
System.out.println("This is a concrete method.");
}
}
class B extends A {
void callme() {
System.out.println("B's implementation of callme.");
}
}
class Abstract {
public static void main(String args[]) {
B b = new B();
b.callme();
b.callmetoo();
}
}
6)接口
一個類的接口可以使用「interface」關鍵字從它的實現中完全抽象出來。因此,它們與 class 類似,只是它們缺少實例變量,並且它們的方法聲明沒有方法體。
接口具有以下特徵:
- ü 幾個類可以實現同一個接口。
- ü 接口可用於實現多重繼承。
- ü 變量是公共的、最終的和靜態的。
- ü 實現類必須實現接口所定義的一整套方法。
- ü 實現接口的類可以定義自己的方法。
示例如下:
interface Area{
final static float pi = 3.14F;
float compute(float x , float y);
}
class Rectangle implements Area{
public float compute (float x, float y){
return (x*y);
}
}
class Circle implements Area{
public float compute (float x, float y){
return (pi * x * x);
}
}
class InterfaceTest{
public static void main (String args[]){
float x = 2.0F;
float y = 6.0F;
Rectangle rect = new Rectangle(); //creating object
Circle cir = new Circle();
float result1 = rect.compute(x,y);
System.out.println("Area of Rectangle = "+ result1);
float result2 = cir.compute(x,y);
System.out.println("Area of Circle = "+ result2);
}
}
7)Java 中的構造函數
特性有:
- ü 構造函數在創建時初始化對象。
- ü 它們與類具有相同的名稱。
- ü 它們沒有任何返回類型,也沒有 void。
- ü 構造函數不能是靜態的、抽象的或最終的。
構造函數可以是:
非參數化或默認構造函數:即使未聲明也可自動調用。
class Box {
double width;
double height;
double depth;
// This is the constructor for Box.
Box() {
System.out.println("Constructing Box");
width = 10;
height = 10;
depth = 10;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
class BoxVol {
public static void main(String args[]) {
// declare, allocate, and initialize Box objects
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
參數化:用來自用戶的預定義值初始化類的欄位。
class Box {
double width;
double height;
double depth;
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
double volume() {
return width * height * depth;
}
}
class BoxVolP {
public static void main(String args[]) {
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box(3, 6, 9);
double vol;
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
11.Java 中的數組
數組是一組由同名引用的同類型變量,是在連續的內存存儲。基本類型的值對象都可存儲在數組中。它提供了代碼優化支持,可以有效地對數據進行排序並隨機訪問它。唯一的缺陷是要使數組有個固定大小(指定個數的元素)。
Java中定義了兩種數組:
1)一維數組:元素存儲在單行中
import java.util.Scanner;
class SingleArray{
public static void main(String args[]){
System.out.println("Enter the length in the array: ");
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int[] numbers = new int [len];
System.out.println("Enter the elements in the array: ");
// int n = s.nextInt();
for(int i=0;i<len;i++){
numbers[i] = sc.nextInt();
}
System.out.println("The elements in the array are: ");
for(int i=0;i<len;i++) {
System.out.print(numbers[i] + " ");
}
System.out.println();
System.out.println("The sum of elements in the array are: ");
int sum =0;
for(int i=0;i<len;i++) {
sum = sum + numbers[i];
}
System.out.println("Sum of elements = " + sum);
}
}
2)多維數組:元素存儲為行和列
class MatrixArray{
public static void main(String args[]){
int [][] m1 = {{1,2,1},{2,1,1},{1,1,2}};
int [][] m2 = {{2,2,2},{1,1,1},{2,1,2}};
int [][] sum = new int [3][3];
//printing matrix
System.out.println("The given matrices are : ");
for(int a=0;a<m1.length;a++) {
for(int b=0;b<m2.length;b++) {
System.out.print(m1[a][b] + " ");
}
System.out.println();
}
System.out.println();
for(int a=0;a<m1.length;a++){
for(int b=0;b<m2.length;b++){
System.out.print(m2[a][b] + " ");
}
System.out.println();
}
//matrix addition
System.out.println("The sum of given 2 matrices is : ");
for(int a=0;a<m1.length;a++){
for(int b=0;b<m2.length;b++){
sum[a][b] = m1[a][b] + m2[a][b];
System.out.print(sum[a][b] + " ");
}
System.out.println();
}
}
}
12. Java 中的字符串
字符串是表示字符序列的非原始數據類型。
String 類型用於聲明字符串變量。
也可以聲明一個字符串數組。
Java 字符串是不可變的;我們無法改變它們。
每當創建字符串變量時,都會創建一個新實例。
1)創建字符串
使用字面量: |
使用new關鍵字: |
String name = 「John」 ; |
String s = new String(); |
2)字符串方法
實現 CharSequence 接口的 String 類為字符串操作任務定義了幾種方法。下面是最常用的字符串方法列表:
Method |
Task Performed |
toLowerCase() |
將字符串轉換為小寫 |
toUpperCase() |
將字符串轉換為大寫 |
replace(『x』, 『y』) |
用' y '替換所有出現的' x ' |
trim() |
刪除開頭和結尾的空白 |
equals() |
如果字符串相等則返回' true ',否則false |
equalsIgnoreCase() |
如果字符串相等,則返回' true ',而不管字符的大小寫 |
length() |
返回字符串的長度 |
CharAt(n) |
給出字符串的第n個字符 |
compareTo() |
返回: 負數if string 1 < string 2 正數if string 1 > string 2 0 if string 1 = string 2 |
concat() |
連接兩個字符串 |
substring(n) |
從n開始返回子字符串 |
substring(n,m) |
返回n和m之間的字符串,不包括m |
toString() |
創建對象的字符串表示形式 |
indexOf(『x』) |
返回x在字符串中第一次出現的位置。 |
indexOf(『x』,n) |
返回從字符串中第n個位置之後x出現的位置 |
ValueOf (Variable) |
將參數值轉換為字符串表示形式 |
顯示字符串排序的程序:
class SortStrings {
static String arr[] = {
"Now", "the", "is", "time", "for", "all", "good", "men",
"to", "come", "to", "the", "aid", "of", "their", "county"
};
public static void main(String args[]){
for(int j = 0; j < arr.length; j++){
for(int i = j + 1; i < arr.length; i++) {
if(arr[i].compareTo(arr[j]) < 0){
String t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
System.out.println(arr[j]);
}
}
}
StringBuffer和StringBuilder
對於可變字符串,我們可以使用 StringBuilder 和 StringBuffer 類,它們也實現了 CharSequence 接口。
這些類代表可增長和可寫的字符接口。
它們會自動增長以為添加內容騰出空間,並且通常預先分配的字符多於實際需要的字符以留出增長空間。
length() 和 capacity() 的區別:
- length():求StringBuffer的長度
- capacity():查找總分配容量
/* StringBuffer 長度與容量 */
class StringBufferTest {
public static void main(String args[]) {
StringBuffer sb = new StringBuffer("Hello");
System.out.println("buffer = " + sb);
System.out.println("length = " + sb.length());
System.out.println("capacity = " + sb.capacity());
}
}
StringBuilder 和StringBuffer
StringBuilder |
StringBuffer |
非同步,高效。 |
同步 |
多線程使用不安全 |
線程安全 |
13.多線程
多任務處理:同時執行多個任務以利用 CPU 的過程。
這可以通過兩種方式實現:
- ü 基於進程的多任務處理。 (多任務處理)
- ü 基於線程的多任務(Multithreading)
1)多任務與多線程:
Multitasking-多任務 |
Multithreading-多線程 |
多個任務同時執行的作業系統概念。 |
將一個進程劃分為兩個或多個並行執行的子進程或線程的概念 |
多個程序可以同時執行。 |
支持同時執行單個程序的多個部分。 |
進程必須在不同的程序或進程之間切換。 |
處理器需要在程序的不同部分或線程之間進行切換。 |
效率更低 |
效率很高 |
program or process in the smallest unit in the environment在環境中最小的單元中運行程序或處理任務 |
線程是最小的單位 |
物有所值 |
昂貴 |
2)線程的生命周期
線程始終處於以下五種狀態之一;如圖所示,它可以通過多種方式從一種狀態轉動到另一種狀態。
- ü 新生線程:創建線程對象。可以使用 start() 方法運行。
- ü 可運行線程:線程已準備好執行並等待處理器。
- ü 運行線程:已經獲得了處理器的執行。
- ü 阻塞線程:阻止線程進入可運行狀態。
- ü 死亡狀態:正在運行的線程在執行完 run() 方法後結束其生命周期。
3)創建線程
- ü 擴展線程類
- ü 實現 Runnable 接口
4)Thread類的常用方法:
方法 |
執行任務 |
public void run() |
由類 MyThread(自定義線程) 繼承 |
public void start() |
使線程轉移到可運行狀態。 |
public void sleep(long milliseconds) |
暫時阻塞或掛起一個線程,以進入可運行狀態,並在隨後指定的毫秒內處於運行狀態。 |
public void yield |
暫時暫停當前正在執行的線程對象,並允許其他線程執行。 |
public void suspend() |
掛起線程,與resume()方法一起使用。 |
public void resume() |
恢復掛起的線 |
public void stop() |
導致線程提前死亡,從而將其移動到死亡狀態。 |
使用線程類創建線程的程序。示例如下:
class A extends Thread{
public void run(){
for(int i=1;i<=5;i++){
System.out.println("From thread A : i " + i);
}
System.out.println("Exit from A ");
}
}
class B extends Thread{
public void run(){
for(int i=0;i<=5;i++){
System.out.println("From thread B : i " + i);
}
System.out.println("Exit from B ");
}
}
class C extends Thread{
public void run (){
for(int k=1;k<=5;k++){
System.out.println("From thread C : k " + k);
}
System.out.println("Exit from C ");
}
}
class ThreadTest{
public static void main(String args[]){
new A().start();
new B().start();
new C().start();
}
}
5)實現Runnable接口
在 Runnable 接口中聲明的 run() 方法是在我們的程序中實現線程所必需的。
該過程包括以下步驟:
- ü 實現 Runnable 接口的類聲明
- ü 實現 run() 方法
- ü 通過定義可實例化「Runnable」類的對象作為所創建線程的目標。
- ü 調用線程的 start() 方法來運行線程。
使用Runnable接口的示例:
class X implements Runnable{
public void run(){
for(int i=0;i<=10;i++) {
System.out.println("Thread X " + i);
}
System.out.println("End of thread X ");
}
}
class RunnableTest{
public static void main(String args[]){
X runnable = new X ();
Thread threadX = new Thread(runnable);
threadX.start();
System.out.println("End of main Thread");
}
}
6)Thread類與Runnable接口
Thread Class |
Runnable Interface |
擴展Thread類本身的派生類是一個線程對象,可以完全控制線程生命周期。 |
Runnable接口只定義線程中執行的工作單元,因此它不控制線程生命周期。 |
派生類不能擴展其他基類 |
允許在必要時擴展基類 |
當程序需要控制線程生命周期時使用 |
當程序需要靈活擴展類時使用。 |
14.Java 中的異常處理
異常是由程序中的運行時錯誤引起的異常或錯誤情況;如果錯誤條件拋出的這個異常對象沒有被正確捕獲和處理,解釋器將顯示錯誤消息。如果我們想避免這種情況並希望程序繼續運行,我們應該嘗試捕獲異常。此任務稱為異常處理。
1)通用Java Exceptions
Exception Type |
Cause of Exception |
ArithmeticException |
caused by math errors |
ArrayIndexOutOfBoundException |
caused by bad array indexes |
ArrayStoreException |
caused when a program tries to store the wrong data type in an array |
FileNotFoundException |
caused by an attempt to access a nonexistent file |
IOException |
caused by general I/O failures. |
NullPointerException |
caused by referencing a null object. |
NumberFormatException |
caused when a conversion between strings and number fails. |
OutOfMemoryException |
caused when there is not enough memory to allocate |
StringIndexOutOfBoundException |
caused when a program attempts to access a non-existent character position in a string. |
java中的異常可以有兩種類型:
l 受檢異常
- ü 藉助 try-catch 塊在代碼本身中顯式處理。
- ü 從java.lang.Exception 類中擴展。
l 非受檢異常
- ü 基本上不在代碼中處理;相反,JVM 會處理此類異常。
- ü 擴展自 java.lang.RuntimeException 類
2)try-catch
try 關鍵字用於作為可能導致錯誤條件並「拋出」異常的代碼塊的前言。關鍵字 catch 定義了一個 catch 塊「捕獲」由 try 塊「拋出」的異常並適當地處理它。
一個代碼在 catch 塊中可以有多個 catch 語句;當 try 塊中產生異常時,多個 catch 語句被視為類似 switch 語句中的情況。
使用 Try 和 Catch 進行異常處理示例如下:
class Error{
public static void main(String args[]){
int a [] = ;
int b = 5;
try {
int x = a[2]/b-a[1];
}catch(ArithmeticException e){
System.out.println("Division by zero");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexError");
}catch(ArrayStoreException e){
System.out.println("Wrong data type");
}
int y = a[1]/a[0];
System.out.println("y = " + y);
}
}
3)finally
finally語句:用於處理之前的任何 catch 語句都沒有捕獲到的異常。無論是否拋出異常,finally塊都保證執行。
我們可以編輯上面的程序並添加以下finally塊。
finally{
int y = a[1]/a[0];
System.out.println("y = " + y);
}
4)拋出你自己的異常
可以使用 throw 關鍵字定義自己的異常。語法形式:
throw new Throwable subclass ;
/* 拋出我們自己的異常 */
import java.lang.Exception;
class MyException extends Exception{
MyException(String message){
super(message);
}
}
class TestMyException{
public static void main(String args[]){
int x = 5 , y = 1000;
try {
float z = (float) x / (float) y ;
if(z < 0.01) {
throw new MyException("Number is too small");
}
}catch (MyException e) {
System.out.println("Caught my exception ");
System.out.println(e.getMessage());
}finally {
System.out.println("I am always here");
}
}
}
15.Java中文件管理
將數據存儲在變量和數組中會帶來以下問題:
- ü 臨時存儲:當變量超出範圍或程序終止時,數據會丟失。
- ü 大數據:很難。
這些問題可以通過使用文件的概念在輔助設備上存儲數據來解決。
存儲在磁碟特定區域中的相關記錄的集合稱為文件。文件通過文件處理的概念來存儲和管理數據。
文件處理包括:
- ü 創建文件
- ü 更新文件
- ü 數據處理
Java 提供了許多文件管理功能,例如:
- ü 數據的讀/寫可根據要求在字節或字符或欄位級上完成。
- ü 它還提供了直接讀/寫對象的能力。
1)流(Stream)
Java 使用流的概念來表示有序的數據序列,即數據流動的路徑。因此,它具有源和目的地。
流分為兩種基本類型:
- Ø 輸入流(Input Stream):提取,即從源文件中讀取數據並將其發送給程序。
- Ø 輸出流(Output Stream):它從程序中獲取數據並發送,即寫入目的地。
流相關類
它們包含在 java.lang.io 包中。它們分為兩組。
- Ø 字節流類(ByteStream):支持處理字節的 I/O 操作。
- Ø 字符流類(CharacterStream):為管理字符的 I/O 操作提供支持。
ByteStream類:旨在提供創建和操作流和文件的讀取/寫入字節的功能。
由於流是單向的,因此有兩種字節流類:
- Ø 輸入流類
- Ø 輸出流類
InputStream類
它們用於讀取 8 位字節,包括稱為 InputStream 的超類。 InputStream 是一個抽象類,定義了輸入功能的方法,例如:
方法 |
描述 |
read( ) |
從輸入流中讀取一個字節 |
read(byte b [ ]) |
將一個字節數組讀入b |
read(byte b [ ], int n, int m) |
從b的第n個字節開始,將m個字節讀入b將一個字節數組讀入b |
available( ) |
告訴輸入中可用的字節數 |
skip(n) |
從輸入流中跳過n個字節 |
reset ( ) |
回到流的起點 |
close ( ) |
關閉輸入流 |
Output類
這些類派生自基類 OutputStream。 OutputStream 是一個抽象類,定義了輸出函數的方法,例如:
方法 |
描述 |
write( ) |
將一個字節寫入輸出流 |
write(byte b[ ]) |
將數組b中的所有字節寫入輸出流 |
write(byte b[ ], int n, int m) |
從數組b的第n個字節開始寫入m個字節 |
close( ) |
關閉輸出流 |
flush( ) |
刷新輸出流 |
2)讀/寫字節
使用的兩個常見子類是 FileInputStream 和 FileOutputStream,它們處理 8 位字節。
FileOutputStream 用於將字節寫入文件,如下所示:
// 將字節寫入文件
import java.io.*;
class WriteBytes{
public static void main(String args[]){
bytes cities [] = {'C','A','L','I','F','O','R','N','I','A', '\n', 'V','E','G','A','S','\n','R','E','N','O','\n'};
//Create output file stream
FileOutputStream outfile = null;
try {
//connect the outfile stream to "city.txt"
outfile = new FileOutputStream("city.txt");
//Write data to the stream
outfile.write(cities);
outfile.close();
}catch(IOException ioe){
System.out.println(ioe);
System.exit(-1);
}
}
}
FileIntputStream 用於從文件中讀取字節,如下所示:
//從文件中讀取字節
import java.io.*;
class ReadBytes{
public static void main(String args[]){
//Create an input file stream
FileInputStream infile = null;
int b;
try{
//connect the infile stream to required file
infile = new FileInputStream(args [ 0 ]);
//Read and display
while( (b = infile.read ( ) ) !=-1){
System.out.print((char) b );
}
infile.close();
}catch(IOException ioe){
System.out.println(ioe);
System.exit(-1);
}
}
}
3)CharacterStream類
兩種字符流類:
ReaderStream類
- ü 旨在從文件中讀取字符。
- ü 類Reader 是所有其他類的基類。
- ü 這些類與輸入流類相似,只是它們的基本信息單元不同,ReaderStream使用字符。
WriterStream類
- ü 對文件執行所有輸出操作。
- ü 寫字符
- ü Writer 類是一個抽象類,它是基類,具有與 OutputStream 相同的方法。
讀/寫字符
用於處理文件中字符的 Reader 和 Writer 類的兩個子類是 FileReader 和 FileWriter。
// 將字符從一個文件複製到另一個文件
import java.io.*;
class CopyCharacters{
public static void main (String args[]) {
//Declare and create input and output files
File inFile = new File("input.dat");
File outFile = new File("output.dat");
FileReader ins = null; //creates file stream ins
FileWriter outs = null; //creates file stream outs
try{
ins = new FileReader(inFile); //opens inFile
outs = new FileWriter(outFile); //opens outFile
//Read and write
int ch;
while((ch = ins.read( ))!=-1){
outs.write(ch);
}
}catch(IOException e){
System.out.println(e);
System.exit(-1);
}finally{
try{
ins.close();
outs.close();
}catch (IOException e){}
}
}
}
16.Java 集合
集合框架包含在 java.util 包中,定義了一組用於操作集合的接口及其實現,集合充當一組對象的容器。
1)接口
集合框架包含Collection、Map、Iterator等多種接口。
接口及其說明如下:
接口名 |
描述 |
Collection |
collection of elements |
List (extends Collection) |
sequence of elements |
Queue (extends Collection) |
the special type of list |
Set (extends Collection) |
collection of unique elements |
SortedSet (extends Set) |
sorted collection of unique elements |
Map |
collection of key and value pairs, which must be unique |
SortedMap (extends Map) |
sorted collection of key-value pairs |
Iterator |
an object used to traverse through a collection |
List (extends Iterator) |
the object used to traverse through a sequence |
2)集合類
集合框架中可用的類實現了集合接口和子接口。它們還實現了 Map 和 Iterator 接口。
下表列出了類及其對應的接口:
Class |
Interface |
AbstractCollection |
Collection |
AbstarctList |
List |
Abstract |
Queue |
AbstractSequentialList |
List |
LinkedList |
List |
ArrayList |
List, Cloneable and Serializable |
AbstractSet |
Set |
EnumSet |
Set |
HashSet |
Set |
PriorityQueue |
Queue |
TreeSet |
Set |
Vector |
List, Cloneable and Serializable |
Stack |
List, Cloneable and Serializable |
Hashtable |
Map, Cloneable and Serializable |
3)數組列表實現
// 使用數組列表類的方法
import java.util.*;
class Num{
public static void main(String args[]){
ArrayList num = new ArrayList ();
num.add(9);
num.add(12);
num.add(10);
num.add(16);
num.add(6);
num.add(8);
num.add(56);
//printing array list
System.out.println("Elements : ");
num.forEach((s) -> System.out.println(s));
//getting size
System.out.println("Size of array list is: ");
num.size();
//retrieving specific element
int n = (Integer) num.get(2);
System.out.println(n);
//removing an element
num.remove(4);
//printing array list
System.out.println("Elements : ");
num.forEach((s) -> System.out.println(s));
}
}
鍊表實現
import java.util.Scanner;
class LinkedList{
public static void main (String args[]) {
Scanner s = new Scanner(System.in);
List list = new List();
System.out.println("Enter the number of elements you want to enter in LL : ");
int num_elements = s.nextInt();
int x;
for(int i =0;i<=num_elements;i++){
System.out.println("Enter element : ");
x = s.nextInt();
list.insert(x);
}
System.out.println(">>>>> LINKED LIST AFTER INSERTION IS : ");
list.print();
int size = list.count();
System.out.println(">>>>> SIZE OF LL => "+size);
System.out.println("Enter the node to be inserted in the middle: ");
int mid_element = s.nextInt();
list.insertMiddle(mid_element);
System.out.println(">>>> LL AFTER INSERTING THE NEW ELEMENT IN THE MIDDLE ");
list.print();
}
}
HashSet 實現
import java.util.*;
class HashSetExample{
public static void main(String args[]){
HashSet hs = new HashSet();
hs.add("D");
hs.add("W");
hs.add("G");
hs.add("L");
hs.add("Y");
System.out.println("The elements available in the hash set are :" + hs);
}
}
TreeSet 實現
import java.util.*;
class TreeSetExample{
public static void main(String args[]){
TreeSet ts = new TreeSet();
ts.add("D");
ts.add("W");
ts.add("G");
ts.add("L");
ts.add("Y");
System.out.println("The elements available in the tree set are :" + ts);
}
}
Vector實現
import java.util.*;
class VectorExample{
public static void main(String args[]){
Vector fruits = new Vector ();
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grapes");
fruits.add("Pineapple");
Iterator it = fruits.iterator();
while (it.hasNext()){
System.out.println(it.next);
}
}
}
Stack類實現
import java.util.*;
public class StackExample{
public static void main (String args[]){
Stack st = new Stack ();
st.push("Java");
st.push("Classes");
st.push("Objects");
st.push("Multithreading");
st.push("Programming");
System.out.println("The elements in the Stack : " + st);
System.out.println("The elements at the top of Stack : " + st.peek());
System.out.println("The elements popped out of the Stack : " + st.pop());
System.out.println("The elements in the Stack after pop of the element : " + st);
System.out.println("The result of search : " + st.search ("r e"));
}
}
HashTable類實現
import java.util.*;
public class HashTableExample{
public static void main (String args[]){
Hashtable ht = new Hashtable();
ht.put("Item 1","Apple");
ht.put("Item 2","Orange");
ht.put("Item 3","Grapes");
ht.put("Item 4","Pine");
ht.put("Item 5","Kiwi");
Enumeration e = ht.keys();
while(e.hasMoreElements()){
String str = (String) e.nextElement();
System.out.println(ht.get(str));
}
}
}
17.Java內存管理
內存是以二進位格式表示的數據集合。
內存管理是:
- ü 分配新對象的過程
- ü 正確刪除未使用的對象(垃圾收集)
內存管理描述示例:
- ü 當一個方法被調用時,幀被創建在棧(stack)頂。
- ü 一旦方法完成,控制流返回到調用方法,並刷新其相應的堆棧幀。
- ü 局部變量在(stack)中創建。
- ü 實例變量是在堆(heap)中創建的,是它們所屬對象的一部分。
- ü 在棧(stack)中創建引用變量。
18.常見的Java 編碼問題
輸入半徑並列印直徑、周長和面積
這是代碼:
import java.util.Scanner;
class Circle{
public static void main (String args []){
double r,dia,peri,area ;
System.out.println("Enter the radius of circle : ");
Scanner s = new Scanner (System.in);
r = s.nextDouble();
dia = 2*r;
peri = 2*Math.PI*r;
area = Math.PI*r*r;
System.out.printf("The dia of circle is : %.2f \n", dia);
System.out.printf("The peri of circle is : %.2f \n", peri);
System.out.printf("The area of the circle is : %.2f \n", area);
}
}
列印x和y之間的所有偶數。代碼如下:
import java.util.Scanner;
class EvenOdd{
public static void main (String args[]){
int x,y;
Scanner s = new Scanner (System.in);
System.out.println("Enter the values x , y : ");
x = s.nextInt();
y = s.nextInt();
System.out.println(" **** EVEN NUMBERS BETWEEN GIVEN RANGE ARE **** >> ");
int count = x;
while(count <=y){
if(count % 2 == 0) {
System.out.println(count);
}
count ++;
}
}
}
檢查給定的數是否為素數,代碼如下:
import java.util.Scanner;
class Prime{
public static void main (String args[]){
double num;
int n;
boolean isPrime = true;
Scanner s = new Scanner(System.in);
System.out.println("Enter the number to check :");
num=s.nextDouble();
n = (int) Math.sqrt(num);
for(int i=2;i<=n;i++){
if(num % i == 0) {
isPrime = false;
}else{
isPrime = true;
}
}
if(isPrime){
System.out.println("***** NUMBER IS PRIME !!!! ****** ");
}else{
System.out.println("***** NUMBER IS NOT PRIME !!!! ****** ");
}
}
}
檢查輸入的數字是否為回文,代碼如下:
import java.util.Scanner;
class Palindrome{
public static void main(String args[]){
int num,reverse=0,mode;
Scanner s = new Scanner(System.in);
System.out.println("Enter a number to check for Palindrome: ");
num = s.nextInt();
int number = num;
while(num!=0){
//System.out.println(" number entering = "+num);
mode = num % 10;
//System.out.println(" mode = "+mode);
reverse =(reverse * 10 )+ mode;
//System.out.println(" reverse = "+reverse);
num = num/10;
//System.out.println(" new num = "+num);
}
//System.out.println(" reverse out = "+reverse);
if(reverse == number){
System.out.println(" **** PALINDROME !!! **** ");
}else{
System.out.println(" **** NOT A PALINDROME !!! **** ");
}
}
}
輸入如下圖形:
*
* *
* * *
* * * *
* * * * *
代碼如下:
import java.util.Scanner;
class TriStars{
public static void main(String args[]){
for(int i=0;i<=5;i++){
for(int j=0;j<i;j++){
System.out.print(" * ");
}
System.out.println();
}
System.out.println();
}
}
19.小結
創建於 1995 年的面向對象編程 Java 旨在克服模塊化編程的缺陷。 Java 引入了抽象、封裝等概念,以實現健壯和安全的代碼。同樣,多態、繼承和類的概念消除了代碼中的冗餘。此外,Java 提供了實現數組、列表、HashMap 等數據結構的集合接口。 Java 用於網際網路安全、Android 開發、Web 開發等各個領域。