Java語法基礎(chǔ)(一)

類的源文件名必須與類同名郁季。對于所有的類來說,類名的首字母應(yīng)該大寫钱磅。

如果沒有顯式為一個類指定構(gòu)造方法梦裂,編譯器會默認(rèn)提供。

在創(chuàng)建一個類對象的時候盖淡,必須要有構(gòu)造方法年柠,類的構(gòu)造方法名必須與類同名,且可以有多個禁舷。Java中使用new關(guān)鍵字創(chuàng)建對象彪杉。

一個Java的源文件只能有一個Public類毅往,但可以有多個非Public的類牵咙。源文件的名稱需與Public的類的類名保持一致派近。

Package

主要用來對Java中眾多的類、接口進(jìn)行分類洁桌。

如果一個類定義在某個包中渴丸,那么 package 語句應(yīng)該在源文件的首行。

包名通常使用小寫的字母來命名避免與類另凌、接口名字的沖突谱轨。
創(chuàng)建包:

///創(chuàng)建 ` learn.cls`的包
package learn.cls; 
public class Person {
  
}
//在包中加入`Student`類,獨立的源文件
package learn.cls;
public class Student extends Person {
}

包名必須要有與之對應(yīng)的文件目錄結(jié)構(gòu):
learn.cls則必須要有learn/cls這樣的目錄結(jié)構(gòu)吠谢。

import

import + 路徑 (包名土童,類名),用以定位類或源代碼工坊。
import learn.cls.* 編譯器會從ClASSPATH/learn/cls目錄下查找對應(yīng)的類献汗。

如果源文件包含 import 語句,那么應(yīng)該放在 package 語句和類定義之間王污。如果沒有 package 語句罢吃,那么import 語句應(yīng)該在源文件中最前面。

import語句和 package 語句對源文件中定義的所有類都有效昭齐。在同一源文件中尿招,不能給不同的類不同的包聲明。

基本數(shù)據(jù)類型

Java有兩大數(shù)據(jù)類型

  • 內(nèi)置數(shù)據(jù)類型
  • 引用數(shù)據(jù)類型

內(nèi)置數(shù)據(jù)類型

有8種基本數(shù)據(jù)類型:
四種整型:
byte: 8位有符號的整數(shù) 范圍 -128 ~ 127
short: 16位有符號的整數(shù) 范圍 -2^15 ~ 2^15 - 1
int: 32位有符號的整數(shù) 范圍 -2^31 ~ 2^31 - 1
long: 64位有符號的整數(shù) 范圍 -2^63 ~ 2^63 - 1
兩種浮點數(shù):
float: 單精度阱驾,32位 小數(shù)
double: 雙精度就谜,64位 小數(shù)
其他:
boolean : true or false
char : 單一的 16Unicode 字符

引用類型

對象、數(shù)組都是引用數(shù)據(jù)類型里覆。
所有引用類型的默認(rèn)值都是null吁伺。
一個引用變量可以用來引用任何與之兼容的類型。

Java常量

Java 中使用final 關(guān)鍵字來修飾常量租谈,聲明方式和變量類似:

final double PI = 3.1415927;

byte篮奄、int、long割去、short都可以用十進(jìn)制窟却、16進(jìn)制以及8進(jìn)制的方式來表示。
當(dāng)使用字面量的時候呻逆,前綴 0表示 8 進(jìn)制夸赫,而前綴 0x代表 16 進(jìn)制, 例如:

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

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

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

自動類型轉(zhuǎn)換

整型咖城、實型(常量)茬腿、字符型數(shù)據(jù)可以混合運算呼奢。運算中,不同類型的數(shù)據(jù)先轉(zhuǎn)化為同一類型切平,然后進(jìn)行運算握础。
轉(zhuǎn)換順序由低到高依次為:

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

數(shù)據(jù)類型轉(zhuǎn)換必須滿足如下規(guī)則:

  1. 不能對boolean類型進(jìn)行類型轉(zhuǎn)換。
  2. 不能把對象類型轉(zhuǎn)換成不相關(guān)類的對象悴品。
  3. 在把容量大的類型轉(zhuǎn)換為容量小的類型時必須使用強制類型轉(zhuǎn)換禀综。
  4. 浮點數(shù)到整數(shù)的轉(zhuǎn)換是通過舍棄小數(shù)得到,而不是四舍五入.

強制類型轉(zhuǎn)換

int x = 128;
byte y = (byte) x; // y = -128 位數(shù)不足苔严,溢出
double d = 7.9D;
 int e = (int)d; //7

整數(shù)的默認(rèn)類型為int;
小數(shù)默認(rèn)是 double 類型定枷,在定義 float 類型時必須在數(shù)字后面跟上 F 或者 f

Java的變量

Java中變量的聲明與其他語言大同小異届氢,基本都是 Type Identifier = value欠窒。

局部變量

局部變量不會有默認(rèn)值,訪問修飾符也不能作用于局部變量退子,必須初始化才能使用

public void pupAge(){
      ///錯誤
      int age;  
     ///正確
      int age = 0;  
      age = age + 7;
      System.out.println("小狗的年齡是 : " + age);
   }

實例變量

當(dāng)一個對象被實例化之后侣夷,每個實例變量的值就跟著確定窿给;實例變量在對象創(chuàng)建的時候創(chuàng)建组橄,在對象被銷毀的時候銷毀帆赢;實例變量可以聲明在使用前或者使用后;訪問修飾符可以修飾實例變量壤靶;實例變量具有默認(rèn)值缚俏。數(shù)值型變量的默認(rèn)值是0,布爾型變量的默認(rèn)值是false贮乳,引用類型變量的默認(rèn)值是null忧换。變量的值可以在聲明時指定,也可以在構(gòu)造方法中指定向拆;

Java的修飾符

Java中的修飾符有兩種:

訪問修飾符

用來對類亚茬、方法、構(gòu)造方法浓恳、變量的訪問設(shè)置不同的權(quán)限刹缝。

  1. public : 范圍:所有類可見;修飾對象:類颈将、方法梢夯、接口、變量
  2. protected : 范圍:同一包中的類和所有子類可見晴圾,修飾對象:方法颂砸、變量;不能修飾類
  3. private:范圍:同一類內(nèi)可見,修飾對象:方法人乓、變量勤篮;不能修飾類
  4. default:默認(rèn)訪問修飾符,不使用任何關(guān)鍵字色罚;同一包中可見碰缔;修飾對象:類、接口保屯、方法手负、變量涤垫。

接口里的變量都隱式聲明為 public static final,而接口里的方法默認(rèn)情況下訪問權(quán)限為 public姑尺。

protected修飾符有個兩個點需要分析說明:

  • 子類與基類在同一個包內(nèi),被聲明為 protected 的變量蝠猬、方法和構(gòu)造器能被同一個包中的任何其他類訪問切蟋。
  • 子類與子類不在同一個包內(nèi),那么在子類中榆芦,子類實例可以訪問其從基類繼承而來的 protected 方法柄粹,而不能訪問基類實例的protected方法。示例:
///基類在包`Animals `中
package Animals;
public class Animals {
    protected void run() {
        System.out.print("跑");
    }
    protected void  eat() {
        System.out.print("吃飯");
    }
}
///子類在包 learn.cls中
package learn.cls;
import Animals.Animals;
public class Dog extends Animals {
    @Override
    protected void eat() {
        this.run();
        System.out.print("吃屎");
    }
}

// 在包learn.cls的其他類中創(chuàng)建Dog實例并訪問基類被protected修飾的方法
Dog dog = new Dog();
dog.eat(); ///?
dog.run();//無法訪問匆绣,編譯器會報錯 ?
///但是基類的run方法在子類是可在直接訪問的驻右,

子類能訪問 protected 修飾符聲明的方法和變量,這樣就能保護(hù)不相關(guān)的類使用這些方法和變量崎淳。如果我們只想讓該方法對其所在類的子類可見堪夭,則將該方法聲明為 protected

訪問控制和方法繼承規(guī)則

  • 父類聲明的public方法拣凹,在子類中也必須為public;
  • 父類聲明的protected方法森爽,在子類中要么為Public,要么protected但不能為private
  • 父類聲明的private方法嚣镜,不能被子類繼承爬迟;

非訪問修飾符

  • static 修飾符,用來修飾類方法和類變量菊匿。
  • final 修飾符付呕,用來修飾類、方法和變量跌捆,final 修飾的類不能夠被繼承徽职,修飾的方法不能被繼承類重新定義,修飾的變量為常量疹蛉,是不可修改的活箕。
  • abstract 修飾符,用來創(chuàng)建抽象類和抽象方法。如果一個類包含抽象方法育韩,那么該類一定要聲明為抽象類克蚂。
  • synchronizedvolatile 修飾符,主要用于線程的編程筋讨。

synchronized 關(guān)鍵字聲明的方法同一時間只能被一個線程訪問埃叭。synchronized修飾符可以應(yīng)用于四個訪問修飾符。

volatile 修飾的成員變量在每次被線程訪問時悉罕,都強制從共享內(nèi)存中重新讀取該成員變量的值赤屋。而且,當(dāng)成員變量發(fā)生變化時壁袄,會強制線程將變化值回寫到共享內(nèi)存类早。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值嗜逻。
一個 volatile 對象引用可能是null涩僻。

///`synchronized `
public synchronized void showDetails(){
.......
}
///`volatile `
private volatile boolean active;

transient 修飾符:序列化的對象包含被 transient 修飾的實例變量時,java 虛擬機(JVM)跳過該特定的變量栈顷。即:用它修飾的變量被序列化不會被持久化逆日。

抽象方法是一種沒有任何實現(xiàn)的方法,該方法的具體實現(xiàn)由子類提供萄凤。抽象方法不能被聲明成 finalstatic室抽。任何繼承抽象類的子類必須實現(xiàn)父類的所有抽象方法,除非該子類也是抽象類靡努。
如果一個類包含若干個抽象方法坪圾,那么該類必須聲明為抽象類。抽象類可以不包含抽象方法颤难。
抽象方法的聲明以分號結(jié)尾神年,例如:public abstract sample();

Java 運算符

Java中的運算符與其他語言運算符基本一致行嗤,分為:

  • 算數(shù)運算符
  • 自增/減運算符:a++已日、a--、++a栅屏、--a
  • 關(guān)系運算符
  • 位運算符: 與運算 同1 ? 1 : 0 或運算: 同0 飘千? 0 : 1 異或 位值相同 ? 0 : 1
  • 邏輯運算符
  • 賦值運算符
  • 條件運算符栈雳、三元運算符

特有的運算符:
instanceof 運算符: 該運算符用于操作對象實例护奈,檢查該對象是否是一個特定類型(類類型或接口類型)。 運算符使用的格式: ( Object reference variable ) instanceof (class/interface type)

boolean istrue = "abcd" instanceof  String; // result: true

Java的循環(huán)結(jié)構(gòu)

Java中有三種主要的循環(huán)結(jié)構(gòu)哥纫,和其他語言一致霉旗,分為:

  • while 循環(huán)
  • do…while 循環(huán)
  • for循環(huán)

其中for循環(huán)在Java中另一種使用方式:增強for循環(huán):

int[] numbers = {1,2,3,4,5};
for(int item : numbers) {
    System.out.println(item);
}

Java的Number與Math

Numer:將基本數(shù)據(jù)類型的包裝成類,java中的基本數(shù)據(jù)類型都有自己的包裝類。

///左側(cè):基本數(shù)據(jù)類型
///右側(cè):包裝后的類
byte -> Byte  //extends Number extends Object
short -> Short //extends Number extends Object
int -> Integer //extends Number extends Object
long -> Long //extends Number extends Object
float -> Float //extends Number extends Object
double -> Double //extends Number extends Object

boolean -> Boolean //extends Object
char -> Character //extends Object

Boolean boolobj = Boolean.TRUE;
Character charobj1 = 'e'; //e
Character charobj2 = '\u0065'; //e
System.out.println(charobj);

關(guān)于運算

Integer x = 5;
int y = 10
x =  x + y;
System.out.println(x);  //15

關(guān)于Math

int a = -10;
Integer b = -40;
a = Math.abs(a);
b = Math.abs(b);
a = a + b;
System.out.println(a); // 50

Java中的Character

Character 類用于對單個字符進(jìn)行操作厌秒。
將一個char類型的參數(shù)傳遞給需要一個Character類型參數(shù)的方法時读拆,那么編譯器會自動地將char類型參數(shù)轉(zhuǎn)換為Character對象

Character charobj1 = 'e'; //e
Character charobj2 = '\u0065'; //e
if (Character.isDigit(charobj1)) {
    System.out.println("是數(shù)字");
}
String str = Character.toString(charobj2);
System.out.println(str);//e

Java中的字符串

  • 創(chuàng)建字符串
String string = "String"; /// 存儲在公共池
String heapStr = new String("String"); /// 存儲在堆中
char[] chars = {'h','e','l','l','o'};
String heapStrByChar = new String(chars);
System.out.printf("公共池:%s,堆字符串:%s\n",string,heapStrByChar);//公共池:String,堆字符串:hello
  • 字符串操作
///獲取字符串長度
int length = heapStrByChar.length();/// 5
///拼接兩個字符串
string = heapStrByChar.concat(string); //Stringhello
///字符串格式化
String format = String.format("公共池:%s,堆字符串:%s\n",string,heapStrByChar);
System.out.println(format);

注意:String 類是不可改變的,所以一旦創(chuàng)建了 String對象鸵闪,那它的值就無法改變了
如果需要改變需要用到StringBufferStringBuilder

///StringBuilder
///參數(shù)提示 cmd + p
StringBuilder sb = new StringBuilder(10);
sb.append("hello");
sb.insert(5,'!');
sb.append(new char[]{'B','o','b'});
System.out.println(sb);//hello!Bob
sb.delete(3,6);
String finalStr = sb.toString();
System.out.println(finalStr);///helBob

///StringBuffer
StringBuffer sbf = new StringBuffer("hello");
sbf.append('!');
sbf.append(new  char[]{'j','a','v','a'});
sbf.insert(0,"smile");
sbf.insert(5,' ');
System.out.println(sbf);//smile hello!java
sbf.deleteCharAt(11);
String res = sbf.toString();
System.out.println(res);//smile hellojava

StringBuilder 類在 Java 5 中被提出檐晕,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)。
由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢蚌讼,所以多數(shù)情況下建議使用 StringBuilder 類辟灰。

Java數(shù)組

  • 數(shù)組聲明
///首選
dataType [] arrayVar;
///效果一致,非首選
dataType arrayVar[]; 
  • 數(shù)組的創(chuàng)建
int[] array = new int[10];
array[0] = 1;
array[1] = 2;
int[] array = {1,2,3,4,4,5};
for (int x : array) {
    System.out.println(x);
}
  • 多維數(shù)組聲明
///格式
type[][] typeName = new type[typeLength1][typeLength2];
///示例 2行3列的二維整型數(shù)組
int[][] intArray = new int[2][3];
  • 多維數(shù)組的創(chuàng)建
int[] arr = {1,2,3};
int[][] array1 = new int[2][3];
array1[1][0] = 2;
array1[1][1] = 3;
array1[1][2] = 4;
array1[0] = arr;
for (int[] item : array1) {
      for (int x : item) {
             System.out.println(x);
       }
  }
  • 通過Arrays類的類方法篡石,執(zhí)行對數(shù)組的操作
int[] array = {1,2,3,4,4,5};
int[] arr = {1,2,3};
Arrays.sort(array);
Arrays.equals(array,arr);
///...

Java日期

  • Date日期創(chuàng)建
Date date = new Date();
///y:1900 + 119 = 2019 ; m: 0~11 
Date date1 = new Date(119,10,20);
// 1$ 表示第一個參數(shù) %t 表示打印時間 %n 換行 %tF 表示以格式`%tY-%tm-%td`輸出日 %tb/%tB 月份的全稱與簡稱
System.out.printf("%1$tY:%1$tm:%1$td %1$tB%n  %2$tF%n",date,date1);
///2022:02:17 二月
///2019-11-20
  • Date日期格式化
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String tfs = df.format(date);
System.out.println(tfs);
  • 字符串轉(zhuǎn)日期Date
SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = "2022-10-01";
try {
  Date date2 = df1.parse(dateStr);
  System.out.printf("%tD%n",date2);//10/01/22
} catch (ParseException e) {
   System.out.println("解析出錯");
}
  • 日期格式化輸出
    詳見:https://www.runoob.com/w3cnote/java-printf-formate-demo.html

  • Calendar的創(chuàng)建與使用
    Calendar類是一個抽象類芥喇,在實際使用時使用其特定的子類的對象,創(chuàng)建對象的過程對程序員來說是透明的夏志,只需要使用getInstance方法創(chuàng)建即可乃坤。

///默認(rèn)當(dāng)前日期
Calendar cld = Calendar.getInstance();
///可修改為表示2018年12月15日的日歷對象
/// month : 0 ~ 11
cld.set(2018,11,15);
///將天數(shù)修改為10
cld.set(Calendar.DATE,10);
System.out.printf("%tF%n",cld.getTime());//2018-12-10
// 獲得年份
int year = cld.get(Calendar.YEAR);
// 獲得月份
int month = cld.get(Calendar.MONTH) + 1;
// 獲得日期
int day = cld.get(Calendar.DATE);
System.out.printf("%s:%s:%s%n",year,month,day);
  • GregorianCalendar
    GregorianCalendarCalendar類的一個具體實現(xiàn)苛让。CalendargetInstance()方法返回一個默認(rèn)用當(dāng)前的語言環(huán)境和時區(qū)初始化的GregorianCalendar對象沟蔑。GregorianCalendar定義了兩個字段:ADBC。這是代表公歷定義的兩個時代狱杰。
GregorianCalendar gcld = new GregorianCalendar();
GregorianCalendar gcld1 = new GregorianCalendar(2019,11,30,23,59,59);
System.out.printf("%tc%n",gcld1.getTime());//周一 12月 30 23:59:59 CST 2019
///其他與`Canlendar`一致

Java正則表達(dá)式

Java中的正則使用主要包括三個類:Pattern瘦材、MatcherPatternSyntaxException

///檢索字符串是否包含與正則匹配的子字符串
String content = "wowaattterww";
///.* regex .* 用來查找字符串中是否包含被`regex`匹配到的字串
String regex = ".*wa{1,2}t{1,3}er.*"; //它匹配 waater/waatter/waattter等
boolean match = Pattern.matches(regex,content);
System.out.println(match);///true
  • 捕獲組
    捕獲組是把多個字符當(dāng)一個單獨單元進(jìn)行處理的方法仿畸,它通過對括號內(nèi)的字符分組來創(chuàng)建食棕。例如,正則表達(dá)式 (dog) 創(chuàng)建了單一分組错沽,組里包含"d"簿晓,"o",和"g"千埃。
    捕獲組是通過從左至右計算其開括號來編號憔儿。例如,在表達(dá)式:"((A)(B(C)))"放可,有四個這樣的組:((A)(B(C))))谒臼、(A)(B(C))耀里、(C)
String content = "wowaattterww888.com";
///分4組,以左括號劃界
/// 0 組 以`reg_p`為整體
//  1 組 只匹配`(\D*)`: 匹配非數(shù)字字符 0個或多個 與反向范圍字符[^0-9]等效
//  2 組 只匹配 `(\d+)`: 匹配數(shù)字字符 1個或多個 與范圍字符[0-9]等效
//  3 組 只匹配 `(.*)` : 匹配單個字符 0個或多個
String reg_p = "(\\D*)(\\d+)(.*)";
Pattern pattern = Pattern.compile(reg_p);
///只能通此來創(chuàng)建`Matcher`類
Matcher matcher = pattern.matcher(content);
//按照慣例蜈缤,第0組表示整個模式。它不包括在此計數(shù)中冯挎。
System.out.println("該正則有"+ (matcher.groupCount() + 1) + "個分組\n");//該正則有4個分組
//Attempts to find the next subsequence of the input sequence that matches the pattern.
boolean found = matcher.find();///匹配到了
if (found) {
    System.out.printf("第一個捕獲組的匹配到的值:%s 開始索引:%d,結(jié)束索引:%d%n",matcher.group(0),matcher.start(0),matcher.end(0));//wowaattterww888.com
    System.out.printf("第二個捕獲組的匹配到的值:%s 開始索引:%d,結(jié)束索引:%d%n",matcher.group(1),matcher.start(1),matcher.end(1));//wowaattterww888.com
    System.out.printf("第三個捕獲組的匹配到的值:%s 開始索引:%d,結(jié)束索引:%d%n",matcher.group(2),matcher.start(2),matcher.end(2));//wowaattterww888.com
    System.out.printf("第四個捕獲組的匹配到的值:%s 開始索引:%d,結(jié)束索引:%d%n",matcher.group(3),matcher.start(3),matcher.end(3));//wowaattterww888.com
}
/*
第一個捕獲組的匹配到的值:wowaattterww888.com 開始索引:0,結(jié)束索引:19
第二個捕獲組的匹配到的值:wowaattterww 開始索引:0,結(jié)束索引:12
第三個捕獲組的匹配到的值:888 開始索引:12,結(jié)束索引:15
第四個捕獲組的匹配到的值:.com 開始索引:15,結(jié)束索引:19
*/
  • Matcher關(guān)鍵方法:lookingAtmatches
///lookingAt與matches
String content = "waattterwo"; ///
String regex = "wa{1,2}t{1,3}er"; //它匹配 waater/waatter/waattter等
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
///輸出:lookingAt匹配底哥?true matches匹配?false
System.out.println("lookingAt匹配?"+ m.lookingAt() + " matches匹配趾徽?"+ m.matches() + "\n" );

lookingAtmatches方法的區(qū)別奶陈,matches要求整個字符串都要與正則匹配,而lookingAt不要求附较,但是它要求從字符串的開始位置就要與正則匹配吃粒,否則就是false。如果將上述代碼:String content = "1waattterwo";,則lookingAt會返回false拒课。

  • Matcher關(guān)鍵方法:replaceFirstreplaceAll

replaceFirstreplaceAll方法用來替換正則表達(dá)式匹配到的文本徐勃。不同的是,replaceFirst替換首次匹配早像,replaceAll替換所有匹配僻肖。

String content = "waa3t2t2t5erwo";
String regex = "\\d+"; //匹配數(shù)字字符 1個或多個
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
String firstReplace = m.replaceFirst("數(shù)字");
String allReplace = m.replaceAll("數(shù)字");
///輸出:replaceFirst:waa數(shù)字t2t2t5erwo  replaceAll:waa數(shù)字t數(shù)字t數(shù)字t數(shù)字erwo
System.out.printf("replaceFirst:%s  replaceAll:%s%n",firstReplace,allReplace);
  • Matcher關(guān)鍵方法:appendReplacementappendTail
    Matcher 類也提供了appendReplacementappendTail 方法用于文本替換:
String content = "waa3t2t2t5erwo";
String regex = "\\d+"; //匹配數(shù)字字符 1個或多個
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
StringBuilder sb = new StringBuilder();
while (m.find()) {
   m.appendReplacement(sb,"數(shù)字");
}
System.out.println(sb.toString());//waa數(shù)字t數(shù)字t數(shù)字t數(shù)字
m.appendTail(sb);
System.out.println(sb.toString());//waa數(shù)字t數(shù)字t數(shù)字t數(shù)字erwo

Java中的方法

大多與其他語言一致,區(qū)別如下:

  • 構(gòu)造方法

構(gòu)造方法和它所在類的名字相同卢鹦,但構(gòu)造方法沒有返回值臀脏。
Java自動為所有的類提供了一個默認(rèn)構(gòu)造方法,默認(rèn)構(gòu)造方法的訪問修飾符和類的訪問修飾符相同(類為 public冀自,構(gòu)造函數(shù)也為 public揉稚;類改為 protected,構(gòu)造函數(shù)也改為 protected)熬粗。一旦定義自己的構(gòu)造方法搀玖,默認(rèn)構(gòu)造方法就會失效。

// 一個簡單的構(gòu)造函數(shù)
class MyClass {
  int x;
 
  // 以下是構(gòu)造函數(shù)
  MyClass(int i ) {
    x = i;
  }
   MyClass() {
     x = 10;
  }
}
  • 可變參數(shù)
    格式:typeName... parameterName 可當(dāng)做數(shù)組用

finalize() 方法

Java 9該方法被棄用了驻呐。
Java 允許定義這樣的方法灌诅,它在對象被垃圾收集器析構(gòu)(回收)之前調(diào)用,這個方法叫做finalize( )含末,它用來清除回收對象猜拾。

///` finalize( )`方法的一般格式
protected void finalize()
{
   // 在這里終結(jié)代碼
}

關(guān)鍵字 protected 是一個限定符,它確保finalize()方法不會被該類以外的代碼調(diào)用佣盒。

Java中的Stream挎袜、File、IO

Stream可以理解為一個數(shù)據(jù)的序列沼撕。輸入流表示從一個源讀取數(shù)據(jù)宋雏,輸出流表示向一個目標(biāo)寫數(shù)據(jù)。

  • 控制臺輸入與輸出
///接收控制臺輸入的輸入流
InputStreamReader reader = new InputStreamReader(System.in);
char c;
do {
   c = (char) reader.read(); ///控制臺輸入完成后务豺,讀取控制臺輸入的字符磨总,one by one
   ///輸入 wwwwwwqq  輸出 wwwwwwq
   System.out.println(c);
} while ( c != 'q');

///轉(zhuǎn)一下,獲取字符流笼沥,讀取整行
BufferedReader bufferedReader = new BufferedReader(reader);
String readStr = bufferedReader.readLine();
System.out.println(readStr);
  • 文件讀寫
    創(chuàng)建一個文件寫入數(shù)據(jù)蚪燕,進(jìn)行讀取輸出到控制臺娶牌,然后刪除該文件。
///創(chuàng)建輸出流馆纳,寫入項目根目錄
File dir = new File("./test/tmp/");
dir.mkdirs();//會創(chuàng)建中間目錄

///文件不存在诗良,寫入過程中會自動創(chuàng)建
File file = new File("./test/tmp/test.text");
try {
    ///此類寫入的是字節(jié)流
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    ///包裝一層寫入 編碼后的字符串
    OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream,"utf-8");
    writer.write("你好,");
    writer.append("我是鮑勃\n");
    ///關(guān)閉寫入流
    writer.close();
    ///關(guān)閉輸出流
    fileOutputStream.close();

    ///讀取文件的內(nèi)容
    FileInputStream fileInputStream = new FileInputStream("./test/tmp/test.text");
    ///讀取解碼后的解碼字符串
    InputStreamReader reader = new InputStreamReader(fileInputStream,"utf-8");
    ///讀取方式1;
    ///ready 文件不空 返回
    StringBuilder sb = new StringBuilder();
    while (reader.ready()){
        sb.append((char) reader.read());
    };
    System.out.println(sb.toString());

    ///讀取方式2:
    ///返回文件預(yù)估長度鲁驶,字節(jié)數(shù)
    ///int charLength = fileInputStream.available() / 2;
    ///char[] chars = new char[charLength];
    ///charLength = reader.read(chars); ///返回讀到的字符數(shù)
    ///String res = new String(chars,0,charLength);
    ///System.out.println(res);

    ///關(guān)閉讀取流
    reader.close();;
    ///關(guān)閉輸入流
    fileInputStream.close();
    ///刪除文件
    System.out.println(file.delete());
    ///刪除目錄 tmp
    dir.delete();
    ///刪除父級目錄 test
    dir.getParentFile().delete();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

Java中的Scanner類

Java 5新特性鉴裹, 它也可以獲取輸入數(shù)據(jù)。

///文件輸出
File file = new File("./test/tmp/test.text");
Scanner scanner = new Scanner(file);
///皆可
while (scanner.hasNext()) {
   System.out.println(scanner.next());///無法獲取空格
}
while (scanner.hasNextLine()) {
   System.out.println(scanner.nextLine());///可以獲取空格
}
scanner.close();
///獲取用戶鍵盤輸入钥弯,進(jìn)行控制臺輸出
Scanner scanner1 = new Scanner(System.in);
while (scanner1.hasNext()) {
   System.out.println(scanner1.next());
}
scanner1.close();

Java中異常

與其他語言径荔,差別不大,具體細(xì)節(jié):https://www.runoob.com/java/java-exceptions.html

Java中的繼承

與其他語言差別不大脆霎,關(guān)鍵字extends总处、implementsfinal

  • 構(gòu)造方法
    子類是不繼承父類的構(gòu)造函數(shù)的睛蛛。
    如果父類的構(gòu)造器帶有參數(shù)鹦马,則必須在子類的構(gòu)造器中顯式地通過super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表。
    如果父類構(gòu)造器沒有參數(shù)忆肾,則在子類的構(gòu)造器中不需要使用super關(guān)鍵字調(diào)用父類構(gòu)造器荸频,系統(tǒng)會自動調(diào)用父類的無參構(gòu)造器。
class SuperClass {
  private int n;
  SuperClass(){
    System.out.println("SuperClass()");
  }
  SuperClass(int n) {
    System.out.println("SuperClass(int n)");
    this.n = n;
  }
}
// SubClass 類繼承
class SubClass extends SuperClass{
  private int n;
  SubClass(){ // 自動調(diào)用父類的無參數(shù)構(gòu)造器
    System.out.println("SubClass");
  }  
  public SubClass(int n){ 
    super(300);  // 調(diào)用父類中帶有參數(shù)的構(gòu)造器
    System.out.println("SubClass(int n):"+n);
    this.n = n;
  }
}
// SubClass2 類繼承
class SubClass2 extends SuperClass{
  private int n;
  SubClass2(){
    super(300);  // 調(diào)用父類中帶有參數(shù)的構(gòu)造器
    System.out.println("SubClass2");
  }  
  public SubClass2(int n){ // 自動調(diào)用父類的無參數(shù)構(gòu)造器
    System.out.println("SubClass2(int n):"+n);
    this.n = n;
  }
}
  • implements
    使用implements 關(guān)鍵字可以變相的使java具有多繼承的特性难菌,使用范圍為類繼承接口的情況试溯,可以同時繼承多個接口(接口跟接口之間采用逗號分隔)。
public interface A {
    public void eat();
    public void sleep();
}
public interface B {
    public void show();
}
public class C implements A,B {
}
  • final
    final 關(guān)鍵字聲明類可以把類定義為不能繼承的郊酒,即最終類;或者用于修飾方法键袱,該方法不能被子類重寫燎窘。

Java的重寫(Override)與重載(Overload)

  • 重寫(Override)
    重寫是子類對父類的允許訪問的方法的實現(xiàn)過程進(jìn)行重新編寫, 返回值和形參都不能改變。即外殼不變蹄咖,核心重寫褐健!
    重寫的規(guī)則:
    1.返回類型為被重寫方法的返回類型及其子類。
    2.訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低澜汤。
    3.聲明為 static 的方法不能被重寫蚜迅,但是能夠被再次聲明。
    4.構(gòu)造方法不能被重寫俊抵。
    5.重寫的方法能夠拋出任何非強制異常谁不,無論被重寫的方法是否拋出異常。但是徽诲,重寫的方法不能拋出新的強制性異常刹帕,或者比被重寫方法聲明的更廣泛的強制性異常吵血,反之則可以。
  • 重載(Overload)
    在一個類里面偷溺,方法名字相同蹋辅,而參數(shù)不同。返回類型可以相同也可以不同挫掏。
    每個重載的方法(或者構(gòu)造函數(shù))都必須有一個獨一無二的參數(shù)類型列表侦另。
    最常用的地方就是構(gòu)造器的重載。

Java多態(tài)

三要素繼承尉共、重寫淋肾、父類指針指向子類。與其他語言一樣爸邢。

Java抽象類&抽象方法

關(guān)鍵字abstract樊卓。
規(guī)則:
1.抽象類,不能被實例化杠河;
2.抽象類可以沒有抽象方法碌尔,但有抽象方法的類必定要是抽象類
3.抽象類中定義的抽象方法,必須要被子類 重寫券敌,除非子類也是抽象類
4.構(gòu)造函數(shù)唾戚、Static修飾的函數(shù),不能為抽象方法待诅。
5.抽象方法只包含一個方法名叹坦,而沒有方法體

Java 接口

Java接口是抽象方法的集合,關(guān)鍵字interface卑雁;一個類通過繼承接口的方式募书,來繼承接口中的抽象方法。接口和類是不同的概念测蹲。類實現(xiàn)接口莹捡,而非繼承接口。

Java中接口可以用來聲明變量扣甲,可指向空指針篮赢,也可以指向?qū)崿F(xiàn)次接口的實例對象。

實現(xiàn)接口的類必須實現(xiàn)接口的所有方法琉挖,除非該類為抽象類启泣。

接口特性:
1.接口中的每個方法都是隱式抽象;接口在聲明的時候也是隱式抽象的示辈; 隱式指定為public abstract寥茫。
2.接口中可以有變量,但只能是public static final修飾的變量顽耳。

  1. Java8中可以定義接口的默認(rèn)方法實現(xiàn)(有方法體)坠敷,關(guān)鍵字default妙同。
  2. Java8中可以定義static方法實現(xiàn)。

實現(xiàn)接口的關(guān)鍵字: implements膝迎,接口實現(xiàn)的規(guī)則:
1.類在實現(xiàn)接口方法時粥帚,無法強制拋出異常;可在接口中或?qū)崿F(xiàn)接口的抽象類中拋出該強制異常限次。
2.一個類可以實現(xiàn)多個接口芒涡。
3.一個接口可以繼承另一個接口。

示例:

public interface Animals {
      void behavior();
      void eat();
      void die();
}

public interface Beasts extends Animals{
    ///定義接口方法
    void run();
    ///定義默認(rèn)方法實現(xiàn)
    default void behavior() {
        System.out.printf("%s行為:地上跑%n", Beasts.BEASTS);
    }
    ///定義變量
    static final String BEASTS = "走獸";
    ///定義靜態(tài)方法
    static String category() {
        return BEASTS + "類";
    }
}
//可多繼承卖漫,比如 `public interface Birds extends Animals,Beasts`
public interface Birds extends Animals {
    ///定義接口方法
    void fly();

    ///默認(rèn)實現(xiàn)`Animals`的方法
    default void behavior() {
        System.out.printf("%s行為:天上飛%n", BIRDS);
    }
    ///定義變量
    static final String BIRDS = "飛禽";
    ///定義靜態(tài)方法
    static String category() {
        return BIRDS + "類";
    }
}
///飛虎费尽!哇
public class FlyTiger implements Beasts, Birds {
    @Override
    public void behavior() {
        Birds.super.behavior();
        Beasts.super.behavior();
        System.out.println("飛虎行為怪異\n");
    }

    @Override
    public void eat() {
        System.out.println(Beasts.category()+":飛虎吃飯");
        System.out.println(Birds.category()+":飛虎吃飯");
    }

    @Override
    public void run() {
        System.out.println("飛虎在地");
    }

    @Override
    public void die() {
        System.out.println("飛虎在地下");
    }
    @Override
    public void fly() {
        System.out.println("飛虎在天");
    }
}

///使用
public static void main(String[] args) {
    Birds birds = new FlyTiger();
     birds.fly();
     Beasts beasts = new FlyTiger();
     beasts.run();
     FlyTiger flyTiger = new FlyTiger();
     flyTiger.eat();
     flyTiger.behavior();
     flyTiger.die();
}

Java 枚舉

  • 枚舉聲明
enum Color {
    BLUE,
    RED,
    GREEN
}
  • 枚舉使用
enum Color {
    BLUE,
    RED,
    GREEN
}
public class EnumTest {
    enum Version {
        DEV,
        RELEASE,
        TRAIL
    }
    public static void main(String[] args) {
        Color color = Color.RED;
        Version version = Version.DEV;
        System.out.println(version);///DEV
        System.out.println(color);///RED
    }
}
  • 枚舉的內(nèi)部實現(xiàn)
enum Color {
    BLUE,
    RED,
    GREEN
}
///內(nèi)部通過`class`實現(xiàn)
class Color {
    public static final Color RED = new Color();
    public static final Color BLUE = new Color();
    public static final Color GREEN = new Color();
}
  • 關(guān)鍵方法
for (Version v : Version.values()) {///Version.values() 枚舉的所有值
     System.out.println(v);
     System.out.println(v.ordinal());//索引
     System.out.println(Version.valueOf("DEV"));//取值
}

枚舉跟普通類一樣可以用自己的變量、方法和構(gòu)造函數(shù)羊始,構(gòu)造函數(shù)只能使用 private 訪問修飾符旱幼,所以外部無法調(diào)用。

public class EnumTest {
    enum Version {
        DEV,
        RELEASE,
        TRAIL;
        private Version(){
            System.out.println("Version枚舉構(gòu)造函數(shù)被"+this.name() + "調(diào)用\n");
        }
        public String getInfo() {
            return "版本信息" + this.name();
        }
    }
    public static void main(String[] args) {
        Version version = Version.RELEASE;///構(gòu)造函數(shù)被調(diào)用
        String info = version.getInfo();///信息打印
        System.out.println(info);
    }
}
  • 枚舉可實現(xiàn)抽象方法
enum Color {
    BLUE{
        public  String getInfo() {
            return "藍(lán)色";
        }
    },
    RED{
        public  String getInfo() {
            return "紅色";
        }
    },
    GREEN{
        public  String getInfo() {
            return "綠色";
        }
    };
    public abstract String getInfo();
}

public class EnumTest {
    public static void main(String[] args) {
       for(Color color : Color.values()) {
           System.out.println(color.getInfo());
       }
    }
}

Java集合框架

Java集合框架主要包括兩種類型的容器:集合(Collection)突委、鍵值對(Map)柏卤。
Collection接口有3種子類型ListSetQueue也是接口匀油。具體可實例化的集合類繼承了實現(xiàn)上述接口的抽象類缘缚。
集合中存儲Java對象。常用的可實例化的集合類:ArrayList敌蚜、LinkedList桥滨、HashSet。常用的Map可實例化的類:HashMap弛车。

ArrayList

ArrayList類是一個可以動態(tài)修改的數(shù)組齐媒,與普通數(shù)組的區(qū)別就是它是沒有固定大小的限制,我們可以添加或刪除元素帅韧。

  • ArrayList的繼承與接口實現(xiàn)關(guān)系
///ArrayList的繼承與接口實現(xiàn)關(guān)系
public interface Collection<E> extends Iterable<E>
public interface List<E> extends Collection<E>
public abstract class AbstractCollection<E> implements Collection<E>
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • ArrayList的關(guān)鍵操作
ArrayList<Integer> arrayList = new ArrayList<>();///創(chuàng)建
arrayList.add(100);///添加對象
arrayList.add(300);
arrayList.add(200);
///小->大排序
arrayList.sort((o1, o2) -> {
    return o1.compareTo(o2);
});
Collections.sort(arrayList);///小->大
///修改
arrayList.set(1, 250);
///查詢
arrayList.get(0);
///刪除
arrayList.remove(1);
///刪除所有
arrayList.clear();
///遍歷一
for (int i = 0; i < arrayList.size(); i++) {
    System.out.println(arrayList.get(i));
}
///遍歷二
for (Integer i : arrayList) {
    System.out.println(i);
}
///遍歷三:可以利用iterator.remove()方法刪除元素
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

LinkedList

LinkedList:鏈表里初,是一種常見的數(shù)據(jù)結(jié)構(gòu),是一種線性表忽舟,但是并不會按線性的順序存儲數(shù)據(jù),而是在每一個節(jié)點里存到下一個節(jié)點的地址淮阐。鏈表可分為單向鏈表和雙向鏈表叮阅。與ArrayList類似,但LinkedList 的增加和刪除的操作效率更高泣特,而查找和修改的操作效率較低浩姥。
以下情況使用 ArrayList:
1.頻繁訪問列表中的某一個元素。
2.只需要在列表末尾進(jìn)行添加和刪除元素操作状您。
以下情況使用 LinkedList :
1.需要通過循環(huán)迭代來訪問列表中的某些元素勒叠。
2.需要頻繁的在列表開頭兜挨、中間、末尾等位置進(jìn)行添加和刪除元素操作眯分。

  • LinkedList的繼承與接口實現(xiàn)關(guān)系
public interface Collection<E> extends Iterable<E>
public interface List<E> extends Collection<E>
public abstract class AbstractCollection<E> implements Collection<E>
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
///多了一層
public abstract class AbstractSequentialList<E> extends AbstractList<E>
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • LinkedList的關(guān)鍵方法
///創(chuàng)建
LinkedList<String> linkedList = new LinkedList<>();
///添加
linkedList.add("java");
linkedList.add("flutter");
linkedList.add("objc");
linkedList.add("swift");
linkedList.add("shell");
///大-> 小 排序
linkedList.sort((o1, o2) -> {
    return o2.compareTo(o1);
});
Collections.sort(linkedList);///小->大
///修改
linkedList.set(4,"php");
///刪除
linkedList.remove("php");
//linkedList.remove(3);
///查詢
linkedList.get(0);
///其他
linkedList.addFirst("vue");
linkedList.addLast("js");
linkedList.removeFirst();
linkedList.removeLast();
///遍歷一
for (int i = 0; i < linkedList.size(); i++) {
    System.out.println(linkedList.get(i));
}
///遍歷二
for (String str :
        linkedList) {
    System.out.println(str);
}
///遍歷三: 可以利用iterator.remove()方法刪除元素
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}

HashSet

HashSet無序的拌汇,不允許有重復(fù)元素的集合,它不是線程安全的弊决。如果多個線程嘗試同時修改HashSet噪舀,則最終結(jié)果是不確定的。 必須在多線程訪問時顯式同步對 HashSet 的并發(fā)訪問飘诗。

  • HashSet的繼承與接口實現(xiàn)關(guān)系
public interface Collection<E> extends Iterable<E>
public interface Set<E> extends Collection<E>
public abstract class AbstractCollection<E> implements Collection<E>
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
  • HashSet關(guān)鍵方法
///創(chuàng)建
HashSet<String> hashSet = new HashSet<>();
///添加
hashSet.add(null);//可添加null
hashSet.add("張飛");
hashSet.add("關(guān)羽");
hashSet.add("劉備");
hashSet.add("趙云");
hashSet.add("趙云");//無法添加重復(fù)元素
///刪除
hashSet.remove("趙云");
///刪除所有
hashSet.clear();
///包含
if (hashSet.contains("劉備")) {
    System.out.println("包含");
}
///遍歷
for (Object obj: hashSet) {
    System.out.println(obj);
}

HashMap

HashMap 是一個散列表与倡,它存儲的內(nèi)容是鍵值對(key-value)映射。
HashMap 實現(xiàn)了 Map 接口昆稿,根據(jù)鍵的 HashCode值存儲數(shù)據(jù)纺座,具有很快的訪問速度,最多允許一條記錄的鍵為null溉潭,不支持線程同步净响。
HashMap 是無序的,即不會記錄插入的順序岛抄。
HashMapkeyvalue 類型可以相同也可以不同别惦,可以是字符串(String)類型的 keyvalue,也可以是整型(Integer)的 key 和字符串(String)類型的 value夫椭。

  • HashMap的繼承與接口實現(xiàn)關(guān)系
public interface Map<K, V> 
public abstract class AbstractMap<K,V> implements Map<K,V>
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
  • HashMap的關(guān)鍵方法
///創(chuàng)建
HashMap<Integer,String> map = new HashMap<Integer,String>();
///添加
map.put(1,"1");
map.put(2,"2");
map.put(3,"3");
///如果沒有則添加
map.putIfAbsent(2,"4");
///修改
map.replace(2,"20");
map.put(2,"22");
///刪除
map.remove(3);
//獲取
map.get(2);///22
System.out.println(map);
///遍歷一
for (Integer key : map.keySet()) {
    System.out.println(map.get(key));
}
///遍歷二
for (String value:map.values()) {
    System.out.println(value);
}
///遍歷三
Iterator<Map.Entry<Integer,String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next().getValue());
}
///遍歷四
ArrayList arrayList =  new ArrayList<>(map.values());
for (int i = 0; i < arrayList.size(); i++) {
    System.out.println(arrayList.get(i));
}

Java中的Object

JavaObject 類是所有類的父類掸掸,也就是說 Java 的所有類都繼承了 Object,子類可以使用 Object 的所有方法蹭秋。
Object類可以顯示繼承扰付,也可以隱式繼承,以下兩種方式時一樣的:

///顯式繼承
pulic class Test extends Object {
}
///隱式繼承
public class test {
}

Java中的泛型

泛型方法

定義泛型方法的規(guī)則:
1.泛型方法需要聲明類型參數(shù)仁讨,類型參數(shù)聲明在函數(shù)返回值類型的前面羽莺,采用尖括號< >包裹。形如:<E>
2.類型參數(shù)聲明可有多個洞豁,尖括號內(nèi)盐固,彼此用逗號,隔開
3.類型參數(shù)能被用來聲明返回值類型,并且能作為泛型方法得到的實際參數(shù)類型的占位符丈挟。
4.泛型方法體的聲明和其他方法一樣刁卜。
5.注意類型參數(shù)只能代表引用型類型,不能是原始類型(像 int曙咽、double蛔趴、char 等)。

///示例
public static <T,S>  T genericsFunc(T param1, S param2) {
    System.out.println(param2);
    return  param1;
}

泛型類

類名后面添加了類型參數(shù)聲明部分例朱,類型參數(shù)聲明部分也包含一個或多個類型參數(shù)孝情,參數(shù)間用逗號隔開鱼蝉。

public class GenericTest<T,U> {
    T type;
    U user;
    public GenericTest(T type, U user){
        this.type = type;
        this.user = user;
    }
    public T getType(){
        return this.type;
    }
    public U getUser(){
        return  this.user;
    }
    public void setType(T type) {
        this.type = type;
    }
    public void setUser(U user) {
        this.user = user;
    }
    public static void main(String[] args) {
        GenericTest<String,String> genericTest = new GenericTest<>("工人","張三");
        genericTest.setType("農(nóng)民");
        System.out.println(genericTest.type);
        System.out.println(genericTest.user);
    }
}

類型通配符與條件限定

類型通配符一般是使用 ? 代替具體的類型參數(shù)。例如 List<?>在邏輯上是 List<String>,List<Integer> 等所有 List<具體類型實參> 的父類箫荡。不需要額外聲明的類型參數(shù)魁亦。

public static void printArray(List<?> arr) {
    System.out.println(arr.get(0));
}

public static void main(String[] args) {
    ArrayList list<String> = new ArrayList<String>();
    list.add("hello");
    printArray(list);
}
  • 限定通配符的類型為特定類型的子類: <? extends T>
public static void printArray(List<? extends Number> arr) {
    System.out.println(arr.get(0));
}

public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<String>();
    list.add("hello");
    //printArray(list);//報錯
    ArrayList<Integer> numlist = new ArrayList<Integer>();
    numlist.add(100);
    printArray(numlist);
}
  • 限定通配符的類型為特定類型的父類: <? super T>
public static void printArray(List<? super Integer> arr) {
    System.out.println(arr.get(0));
}

Java序列化

Java序列化,是將一個Java類對象序列化為字節(jié)序列的過程菲茬,該字節(jié)序列會保存對象的數(shù)據(jù)吉挣,也會保存對象類型關(guān)聯(lián)的所有類型的信息;因此該字節(jié)序列也可以通過反序列化轉(zhuǎn)化為對象婉弹。整個過程基于JVM睬魂,因此該字節(jié)序列支持平臺遷移。

Java的對象支持序列化的條件镀赌,該對象所屬類型必須實現(xiàn)接口java.io.Serializable

Java 序列化機制的主要類ObjectOutputStreamObjectInputStream氯哮。

  • 序列化
    當(dāng)序列化一個對象到文件時, 按照 Java 的標(biāo)準(zhǔn)約定是給文件一個 .ser 擴展名商佛。
public class SerializableTest implements java.io.Serializable {
    public String name;
    public String job;
    public int age;
    public boolean hasJob;
    public transient String intro; ///無法被序列化
}
public static void serialization() {
    ///創(chuàng)建對象
    SerializableTest testObjc = new SerializableTest();
    testObjc.name = "波波";
    testObjc.job = "售貨員";
    testObjc.age = 20;
    testObjc.hasJob = true;
    testObjc.intro = "還歲月以文明";
    try {
        FileOutputStream fileOutputStream = new FileOutputStream("/tmp/test.ser");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        ///對象序列化
        objectOutputStream.writeObject(testObjc);
        fileOutputStream.close();
        objectOutputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

  • 反序列化
public static SerializableTest deserialization() {
    SerializableTest test = null;
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream("/tmp/test.ser");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
        ///反序列化
        test = (SerializableTest) inputStream.readObject();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return test;
}

public static void main(String[] args) {
    serialization();
    SerializableTest obj = deserialization();
    if (obj != null) {
        System.out.println(obj.name);//波波
        System.out.println(obj.job);//售貨員
        System.out.println(obj.age);//20
        System.out.println(obj.hasJob);//true
        System.out.println(obj.intro); ///null
    }
}

Java多線程

線程狀態(tài)

創(chuàng)建->就緒(進(jìn)入就緒隊列喉钢,待JVM調(diào)度)->運行(獲取CPU資源)->死亡;
運行狀態(tài)下良姆,線程可能因為調(diào)用sleep肠虽、waitsuspend進(jìn)入阻塞狀態(tài)玛追。當(dāng)睡眠時間到或重獲CPU資源便會進(jìn)入就緒狀態(tài)税课。主要有三種阻塞:
1.線程運行時調(diào)用wait方法進(jìn)入等待阻塞。
2.同步阻塞痊剖,同步鎖:synchronized韩玩。
3.其他阻塞,如:sleep陆馁、join(等待線程終止或超時或I/O處理完畢)找颓。

線程優(yōu)先級

Java中線程的優(yōu)先級0~10,如果不設(shè)置優(yōu)先級默認(rèn)為5叮贩。

線程創(chuàng)建

  1. 通過實現(xiàn)Runnable接口創(chuàng)建線程

創(chuàng)建一個實現(xiàn)Runnable接口的類击狮,該類需創(chuàng)建一個Thread實例,運行該Thread實例的start()方法益老,讓線程執(zhí)行帘不。

一個實現(xiàn)了Runnable的類可以通過實例化一個Thread實例并將自己作為目標(biāo)傳入,從而在不子類化Thread的情況下運行杨箭。在大多數(shù)情況下,如果你只打算覆蓋run()方法而不覆蓋其他的Thread方法储狭,那么就應(yīng)該使用Runnable接口互婿。

public class ThreadTest {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());///main
        startNewThread("線程1");
    }
    public static void startNewThread(String threadName) {
        ///創(chuàng)建一個實現(xiàn)`Runnable`接口的類
        Runnable runnable = new Runnable() {
            ///實現(xiàn)`run`方法
            ///獲取CPU資源運行任務(wù)
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());///線程1
                try {
                    ///阻塞 5s
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(threadName +"休眠結(jié)束");///線程1休眠結(jié)束
            }
        };
        ///創(chuàng)建線程
        Thread t = new Thread(runnable,threadName);
        ///就緒捣郊,加入線程隊列,
        t.start();
    }
}
  1. 通過繼承Thread來創(chuàng)建線程
public class ThreadTest extends Thread {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());///main
        ThreadTest customThread = new ThreadTest("線程1");//線程1
        customThread.start();
    }

    public ThreadTest(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());///線程1
        try {
            ///阻塞 5s
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName() +"休眠結(jié)束");///線程1休眠結(jié)束
    }
}
  1. 通過CallableFuture創(chuàng)建線程
public class ThreadTest {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());///main
        ///創(chuàng)建一個實現(xiàn)`Callable`接口的類
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return 100;
            }
        };
        ///使用`FutureTask`包裝
        FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
        //創(chuàng)建線程慈参,并將`FutureTask`作為線程執(zhí)行對象
        Thread thread = new Thread(futureTask);
        ///使線程處于就緒狀態(tài)
        thread.start();
        try {
           ///取值
            Integer integer = futureTask.get();
            System.out.println(integer);///100
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呛牲,一起剝皮案震驚了整個濱河市粹舵,隨后出現(xiàn)的幾起案子狼速,更是在濱河造成了極大的恐慌,老刑警劉巖粤策,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壮锻,死亡現(xiàn)場離奇詭異琐旁,居然都是意外死亡,警方通過查閱死者的電腦和手機猜绣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門灰殴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掰邢,你說我怎么就攤上這事牺陶。” “怎么了辣之?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵掰伸,是天一觀的道長。 經(jīng)常有香客問我怀估,道長狮鸭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任奏夫,我火速辦了婚禮怕篷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酗昼。我一直安慰自己廊谓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布麻削。 她就那樣靜靜地躺著蒸痹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呛哟。 梳的紋絲不亂的頭發(fā)上叠荠,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音扫责,去河邊找鬼榛鼎。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的者娱。 我是一名探鬼主播抡笼,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼黄鳍!你這毒婦竟也來了推姻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤框沟,失蹤者是張志新(化名)和其女友劉穎藏古,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忍燥,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡拧晕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了灾前。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片防症。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哎甲,靈堂內(nèi)的尸體忽然破棺而出蔫敲,到底是詐尸還是另有隱情,我是刑警寧澤炭玫,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布奈嘿,位于F島的核電站,受9級特大地震影響吞加,放射性物質(zhì)發(fā)生泄漏裙犹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一衔憨、第九天 我趴在偏房一處隱蔽的房頂上張望叶圃。 院中可真熱鬧,春花似錦践图、人聲如沸掺冠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽德崭。三九已至,卻和暖如春揖盘,著一層夾襖步出監(jiān)牢的瞬間眉厨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工兽狭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留憾股,地道東北人鹿蜀。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像荔燎,于是被迫代替她去往敵國和親耻姥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容