Java常用API及基礎(chǔ)語(yǔ)法

一、Object類中的幾個(gè)常用方法:

1嗤练、toString

①作用:將對(duì)象轉(zhuǎn)化成字符串,一般都會(huì)重寫(xiě)該方法(默認(rèn)輸出:類名@對(duì)象內(nèi)存地址);
②直接輸出類會(huì)自動(dòng)調(diào)用toString方法丐怯;
System.out.println(cat); //輸出com.test.javase.Cat@1590164

2翔横、equals

①作用:判斷兩個(gè)對(duì)象是否相等(默認(rèn)使用==判斷读跷,所以要重寫(xiě)該方法);

3禾唁、finalize

①作用:如果希望在對(duì)象銷毀時(shí)執(zhí)行一段代碼效览,可以將其寫(xiě)到finalize()方法當(dāng)中;
②源碼:protected void finalize() throws Throwable { }荡短;
③這個(gè)方法不需要程序員手動(dòng)調(diào)用丐枉,JVM垃圾回收器負(fù)責(zé)調(diào)用這個(gè)方法;
④執(zhí)行時(shí)機(jī):當(dāng)一個(gè)java對(duì)象即將被垃圾回收器回收的時(shí)候掘托,垃圾回收器負(fù)責(zé)調(diào)用finalize()方法

4瘦锹、hashCode

①作用:返回一個(gè)對(duì)象的哈希代碼值,通過(guò)將該對(duì)象的內(nèi)存地址轉(zhuǎn)換成一個(gè)整數(shù),函數(shù)返回一個(gè)int型數(shù)據(jù)

二弯院、數(shù)組

1辱士、一維數(shù)組初始化

靜態(tài)初始化:int[] a = {100, 200, 102};
動(dòng)態(tài)初始化:int[] a = new int[5]; //默認(rèn)值為0
或者[]放在后面:int a[] = new int[10];

2、數(shù)組拷貝

System.arraycopy(原數(shù)組听绳,拷貝開(kāi)始下標(biāo)颂碘,目標(biāo)數(shù)組,拷貝到目標(biāo)數(shù)組的下標(biāo)椅挣,拷貝長(zhǎng)度)

3头岔、二維數(shù)組初始化

靜態(tài)初始化:int[][] a = {{1,2,3},{4,5,6},{7,8,9}};
動(dòng)態(tài)初始化:int[][] a = new int[5][5];

4、Arrays工具類

排序:Arrays.sort
二分查找:Arrays.binarySearch

三鼠证、String類

1切油、字符串都是直接存儲(chǔ)在方法區(qū)的字符串常量池當(dāng)中的

視頻鏈接:https://www.bilibili.com/video/BV1Rx411876f?p=587&spm_id_from=pageDriver&vd_source=451d825d8e1ffcbfd124804db3810f11
"hello":java雙引號(hào)引起來(lái)都是一個(gè)字符串對(duì)象,都會(huì)在字符串常量池中創(chuàng)建一個(gè)新對(duì)象(相同的字符串只會(huì)創(chuàng)建一個(gè))名惩,當(dāng)用new創(chuàng)建String對(duì)象時(shí)澎胡,堆里面的String對(duì)象里面存放的是字符串常量池里面的內(nèi)存地址【兩個(gè)是兩種不同的對(duì)象】
①第一種初始化方式:String s1 = "hello";

String s1 = "hello";
String s2 = "hello";
System.out.println(b == c); 這里打印true

image.png

②第二種初始化方式:String x = new String("xyz");

String x = new String("xyz");
String y = new String("xyz");
System.out.println(b == c); 這里打印false
image.png
2、字符串比較時(shí)避免空指針異常

將username.equals("admin")修改為:
"admin".equals(username)

3娩鹉、String類構(gòu)造函數(shù)

①將byte數(shù)組全部轉(zhuǎn)化為字符串:String s = new String(bytes);

byte[] bytes = {97, 98, 99};    97是a攻谁,98是b,99是c
String s = new String(bytes);
System.out.println(s); 輸出abc

②將char數(shù)組全部轉(zhuǎn)換為字符串:

char[] c = {'a', 'b', 'c'};
String s = new String(c);
System.out.println(s);  輸出abc
4弯予、String各類方法:

①equalsIgnoreCase()
"Abc".equalsIgnoreCase("abc"); true戚宦,【忽略大小寫(xiě)比較是否相等】
②getBytes()
byte[] b = "abcd".getBytes(); [97, 98, 99, 100] 【將字符串轉(zhuǎn)換為byte數(shù)組】
③String.valueOf()
String s1 = String.valueOf(true); 【靜態(tài)方法,可以將非字符串轉(zhuǎn)換成字符串锈嫩,true->"true"】
System.out.println(s1);

5受楼、StringBuffer(線程安全的)

作用:當(dāng)需要頻繁的拼接字符串時(shí),為了避免不斷的在字符串常量池當(dāng)中創(chuàng)建對(duì)象呼寸,可以使用StringBuffer艳汽。StringBuffer底層實(shí)際是一個(gè)byte[]數(shù)組,初始化容量是16对雪;

StringBuffer s = new StringBuffer();
s.append("a");
s.append("b");
s.append("c");
s.append(3.14);
s.append(8);
s.append(true);
System.out.println(s);   結(jié)果:abc3.148true

優(yōu)化:在創(chuàng)建StringBuffer的時(shí)候盡可能給定一個(gè)合適的初始化容量河狐,減少底層數(shù)組的擴(kuò)容次數(shù)。

6瑟捣、StringBuilder(非線程安全的)

StringBuilder跟StringBuffer區(qū)別:StringBuffer的方法都有synchronized關(guān)鍵字修飾馋艺,StringBuffer在多線程環(huán)境下運(yùn)行是安全的,而StringBuilder在多線程下是不安全的迈套。

四捐祠、八種包裝類

1、八種類

Byte桑李、Short踱蛀、Integer窿给、Long、Float星岗、Double填大、Boolean戒洼、Character

2俏橘、裝箱、拆箱

裝箱:基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類
Integer i = new Integer(123);
插箱:包裝類轉(zhuǎn)換為基本數(shù)據(jù)類型
int relValue = i.intValue();

自動(dòng)裝箱:基本數(shù)據(jù)類型自動(dòng)轉(zhuǎn)換為包裝類
Integer i = 123; 【i中保存的還是指向?qū)ο蟮膬?nèi)存地址圈浇,并非123】
自動(dòng)插箱:包裝類自動(dòng)轉(zhuǎn)換為基本數(shù)據(jù)類型
int j = i;

3寥掐、注意點(diǎn)

java為了提高程序的執(zhí)行效率,將[-128到127]之間所有的包裝對(duì)象提前創(chuàng)建好磷蜀,放到一個(gè)方法區(qū)的“整數(shù)型常量池”當(dāng)中召耘,目的是只要用這個(gè)區(qū)間的數(shù)據(jù)不需要再new了,直接從整數(shù)型常量池當(dāng)中取出來(lái)褐隆。
例如:

Integer i = 127;
Integer j = 127;
System.out.println(i == j); true
        
Integer x = 128;
Integer y = 128;
System.out.println(x == y); false

圖解:


image.png

五污它、日期處理

1、格式化時(shí)間 SimpleDateFormat
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(dateFormat.format(date));  結(jié)果:2022-07-01 14:27:12 400
2庶弃、字符串轉(zhuǎn)換成Date類型 SimpleDateFormat

【字符串要保持與創(chuàng)建的SimpleDateFormat 格式一致】

String s = "2022-07-01 14:27:12 400";
Date date1 = dateFormat.parse(s);
System.out.println(date1);
3衫贬、System.currentTimeMillis() 獲取時(shí)間戳

六、數(shù)字處理

1歇攻、格式化數(shù)字
DecimalFormat df = new DecimalFormat("###,###.##");
System.out.println(df.format(3245.62)); 結(jié)果3,245.62

# 代表任意數(shù)字
, 代表千分位
. 代表小數(shù)點(diǎn)
0 代表不夠時(shí)補(bǔ)0

2固惯、高精度數(shù)字BigDecimal

專門用于財(cái)務(wù)軟件之中

BigDecimal d1 = new BigDecimal(100);
BigDecimal d2 = new BigDecimal(200);
System.out.println(d1.add(d2));  結(jié)果:300
3、隨機(jī)數(shù)
Random r = new Random();
System.out.println(r.nextInt(101));   結(jié)果:產(chǎn)生0-100(不包含101)的隨機(jī)整數(shù)
4缴守、枚舉enum

語(yǔ)法:

enum Color{
  YELLOW, RED, BLACK, PINK, GREEN
}

七葬毫、異常

1、java異常處理機(jī)制

①異常在java中以類和對(duì)象的形式存在屡穗,所有異常都是發(fā)生在運(yùn)行階段
②異常的繼承結(jié)構(gòu):
Object下面有Throwable
Throwable下面有兩個(gè)分支:Error(不可處理)和Exception(可處理)
Exception下面有兩個(gè)分支:
ExceptionSubClass:編譯時(shí)異常贴捡,要求在編寫(xiě)程序階段必須先對(duì)這些異常進(jìn)行處理,如果不處理編譯器會(huì)報(bào)錯(cuò)
RuntimeException:運(yùn)行時(shí)異常村砂,編寫(xiě)程序的時(shí)候可以不處理
③編譯時(shí)異常 和 運(yùn)行時(shí)異常的區(qū)別:
編譯時(shí)異常發(fā)生概率高

2栈暇、異常處理

第一種方式:在方法聲明的位置上,使用throws關(guān)鍵字箍镜,拋給上一級(jí)(拋給調(diào)用者源祈,調(diào)用者如果沒(méi)有處理就繼續(xù)上拋,直到拋給main函數(shù)色迂,main函數(shù)拋給JVM香缺,JVM檢查到異常則停止程序運(yùn)行)throw是手動(dòng)拋出異常;【異常上拋】
第二種方式:使用try...catch語(yǔ)句進(jìn)行異常捕捉 歇僧⊥颊牛【異常捕捉】

3锋拖、try...catch

①catch后面小括號(hào)中的類型可以是具體的異常類型,也可以是該異常類型的父類型
②catch可以寫(xiě)多個(gè)祸轮,建議catch的時(shí)候兽埃,精確的一個(gè)個(gè)處理,這樣有利于程序調(diào)試
③catch寫(xiě)多個(gè)的時(shí)候适袜,從上到下柄错,必須遵守從小到大。

4苦酱、異常對(duì)象的常用方法

e.printStackTrace(); 打印異常堆棧信息
String msg = e.getMessage(); 獲取異常簡(jiǎn)單描述信息

5售貌、finally

在finally字句中的代碼是最后執(zhí)行的,且一定會(huì)執(zhí)行疫萤,所以一般在finally語(yǔ)句塊中完成資源的釋放/關(guān)閉
①語(yǔ)法:

try{

}catch (Exception e){

}finally{

}

②面試問(wèn)題
第一種:

try {
    System.out.println("try");
    return;     
} finally{
    System.out.println("finally");  會(huì)執(zhí)行
}

第二種:

try {
    System.out.println("try");
    System.exit(0);  退出JVM
} finally{
    System.out.println("finally"); 不會(huì)執(zhí)行
}

第三種:

int i = 100;
try {
    return i;  i最后返回100
} finally{
    i++;
}
6颂跨、final、finally扯饶、finalize的區(qū)別

final是一個(gè)關(guān)鍵字恒削,表示最終的、不變的尾序,無(wú)法繼承钓丰、無(wú)法覆蓋、無(wú)法重新賦值蹲诀;
finally也是一個(gè)關(guān)鍵字斑粱,與try聯(lián)合使用,使用在異常處理機(jī)制中脯爪,在finally語(yǔ)句塊中的代碼是一定會(huì)執(zhí)行的则北;
finalize()是Object類中的一個(gè)方法,作為方法名出現(xiàn)痕慢,當(dāng)一個(gè)java對(duì)象即將被垃圾回收器回收的時(shí)候尚揣,垃圾回收器負(fù)責(zé)調(diào)用finalize()方法。

7掖举、自定義異常

第一步:編寫(xiě)一個(gè)類繼承 Exception(編譯時(shí)異常) 或者 RuntimeException(運(yùn)行時(shí)異常)快骗;
第二步:提供兩個(gè)構(gòu)造方法,一個(gè)無(wú)參數(shù)的塔次,一個(gè)帶有String參數(shù)的方篮。

八、集合

1励负、集合中任何時(shí)候存儲(chǔ)的都是“引用”

集合不能直接存儲(chǔ)基本數(shù)據(jù)類型

2藕溅、List、Set接口(Map鍵值對(duì))

Collection接口下:
List
Set
①List继榆、Set區(qū)別
List:有序可重復(fù)巾表,有下標(biāo)
Set:無(wú)序不可重復(fù)汁掠,無(wú)下標(biāo)
②List接口的實(shí)現(xiàn)
ArrayList集合底層采用了數(shù)組(非線程安全)
LinkedList集合底層采用了雙向鏈表
Vector集合底層采用了數(shù)組(線程安全)
③Set接口的實(shí)現(xiàn)
HashSet集合底層采用了HashMap集合
TreeSet集合底層采用了TreeMap集合(TreeSet繼承自SortedSet)
HashMap底層是哈希表
TreeMap底層是二叉樹(shù)

3、Iterator迭代器

集合結(jié)構(gòu)只要發(fā)生改變集币,迭代器必須重新獲取
所以在迭代的過(guò)程中不能直接使用集合對(duì)象進(jìn)行刪除(改變了結(jié)構(gòu))考阱,而應(yīng)該使用迭代器提供的remove()方法,該方法刪除的是迭代器指向的當(dāng)前元素(迭代器迭代時(shí)是使用快照鞠苟,如果直接在對(duì)象上調(diào)用remove方法刪除乞榨,沒(méi)有通知迭代器,那么迭代器還是使用的原集合偶妖,就會(huì)報(bào)異常)

循環(huán)的三種方式:

List<String> arg = new ArrayList<String>();
arg.add("hello");
arg.add("Tong");
arg.add("Panda");
        
迭代器:
Iterator<String> it = arg.iterator();
while(it.hasNext()){
    System.out.println(it.next());
}
        
下標(biāo)方式:
for(int i = 0; i < arg.size(); i++){
    System.out.println(arg.get(i));
}
        
增強(qiáng)for循環(huán):
for(String str : arg){
    System.out.println(str);
}
4姜凄、ArrayList
  • ArrayList集合初始化容量是10
  • ArrayList集合底層是Object類型的數(shù)組Object[]
  • 擴(kuò)容1.5倍
  • 建議給定一個(gè)預(yù)估初始容量政溃,減少數(shù)組的擴(kuò)容操作
5趾访、泛型 ArrayList<obj>
  • 泛型這種語(yǔ)法機(jī)制只在程序編譯階段起作用,只是給編譯器參考的(運(yùn)行階段泛型沒(méi)用)
  • 使用了泛型之后集合中儲(chǔ)存的元素類型統(tǒng)一了
  • 自定義泛型:
class Test<E> {
  public void add(E a){
    ...
  }
}
6董虱、增強(qiáng)for循環(huán):foreach(沒(méi)有下標(biāo))
int[] arr = {1,2,3,4,5};
for (int item : arr) {
    System.out.println(item);
}
7扼鞋、Map鍵值對(duì)
  • 注意點(diǎn):
    ①M(fèi)ap與Collection沒(méi)有繼承關(guān)系
    ②Map集合以key、value鍵值對(duì)的形式存儲(chǔ)數(shù)據(jù)
    ③key愤诱、value都是引用數(shù)據(jù)類型
  • 常用方法:
    containsKey云头、
    containsValue、
    get("key")淫半、
    put("id", 123)溃槐、
    remove("key")、
    Set<K> keySet() 獲取Map集合所有的key科吭,返回一個(gè)Set
    Collection<V> values() 獲取Map集合所有的value昏滴,返回一個(gè)Collection
    Set<Map.Entry<K, V>> b = a.entrySet(); 將Map集合轉(zhuǎn)換成Set集合:變?yōu)閕d=123、age=19
  • Map集合的遍歷:
    ①先用keySet()獲取到所有的key对人,然后通過(guò)key遍歷
Map<String, Integer> map = new HashMap<String, Integer>();
Set<String> keys = map.keySet();
for(String k : keys){
    System.out.println(k + ":" + map.get(k));
}

②【效率高】先用entrySet()將Map轉(zhuǎn)成Set谣殊,再遍歷Set獲取到單個(gè)的Map.Entry<K, V>對(duì)象,調(diào)用對(duì)象的getKey()牺弄、getValue()方法獲取key姻几、value值,例:

Set<Map.Entry<String, Integer>> set = map.entrySet();
for(Map.Entry<String, Integer> item : set){
    System.out.println(item.getKey()+ '=' + item.getValue());
}
  • Properties
    Properties是一個(gè)Map集合势告,繼承Hashtable蛇捌,Properties的key和value都是String類型;
    Properties被稱為屬性類對(duì)象咱台;
    Properties是線程安全的络拌;
Properties pro = new Properties();
pro.setProperty("url", "jdbc:mysql://localhost:3306");
pro.setProperty("username", "root");
pro.setProperty("password", "123456");
System.out.println(pro.getProperty("url"));

搭配FileReader 使用
//讀取xml配置文件
FileReader reader = new FileReader("xml");
Properties pro = new Properties(); //key value都是String
//將xml文件鍵值對(duì)加載到pro集合中
pro.load(reader);
//關(guān)閉流
reader.close();
//通過(guò)key獲取value
System.out.println(pro.getProperty("ClassName"));
8、TreeSet

TreeSet集合中的元素是可排序的
視頻鏈接:https://www.bilibili.com/video/BV1Rx411876f?p=709&vd_source=451d825d8e1ffcbfd124804db3810f11

九吵护、IO流

1盒音、IO流的分類:

輸出流
輸入流
字節(jié)流:可以讀任意類型的文件
字符流:只能讀純文本文件

2表鳍、流的四大家族:

java.io.InputStream 字節(jié)輸入流
java.io.OutputStream 字節(jié)輸出流
java.io.Reader 字符輸入流
java.io.Writer 字符輸出流
【注意】:

  • 【類名以Stream結(jié)尾的都是字節(jié)流,以“Reader/Writer”結(jié)尾的都是字符流】
  • 所有的輸出流都實(shí)現(xiàn)了java.io.Flushable接口祥诽,都是可刷新的譬圣,都有flush()方法,輸出流在輸出了之后一定要flush()刷新一下雄坪,將通道/管道中剩余未輸出的數(shù)據(jù)強(qiáng)行輸出(清空管道)厘熟;
    如果沒(méi)有flush()可能會(huì)導(dǎo)致丟失數(shù)據(jù)。
3维哈、常用流
  • 文件流:
    FileInputStream【重點(diǎn)】
    FileOutputStream【重點(diǎn)】
    FileReader
    FileWriter
  • 轉(zhuǎn)換流:(將字節(jié)流轉(zhuǎn)換成字符流)
    InputStreamReader
    OutputStreamWriter
  • 緩沖流:
    BufferedReader
    BufferedWriter
    BufferedInputStream
    BufferedOutputStream
  • 數(shù)據(jù)流:
    DataInputStream
    DataOutputStream
  • 標(biāo)準(zhǔn)輸出流:
    PrintWriter
    PrintStream【重點(diǎn)】
  • 對(duì)象流:
    ObjectInputStream【重點(diǎn)】
    ObjectOutputStream【重點(diǎn)】
4绳姨、FileInputStream的常用方法:

①read():【不傳參默認(rèn)讀一個(gè)字節(jié)并返回該字節(jié);傳入byte數(shù)組則將字節(jié)存入byte數(shù)組中并返回成功讀取的字節(jié)數(shù)】

    public static void main(String[] args){
        FileInputStream fs = null;
        try {
            fs = new FileInputStream("C:\\Users\\Tong\\Desktop\\新建 文本文檔.txt");
            byte[] bytes = new byte[4];
            int readCount = 0; //初始化讀到的字節(jié)數(shù)
            while((readCount = fs.read(bytes)) != -1){
                System.out.print(new String(bytes, 0, readCount));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(fs != null){
                try {
                    fs.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

②available():【返回流當(dāng)中剩余沒(méi)有讀到的字節(jié)數(shù)量】

fs = new FileInputStream("C:\\Users\\Tong\\Desktop\\新建 文本文檔.txt");
byte[] bytes = new byte[fs.available()];  //不適合大文件
fs.read(bytes);
System.out.print(new String(bytes));

③skip():【跳過(guò)幾個(gè)字節(jié)不讀】

5阔挠、FileOutputStream的常用方法

①構(gòu)造方法:

fs = new FileOutputStream("文本文檔");
fs = new FileOutputStream("文本文檔", true); 帶上true表示以追加的方式在文件末尾寫(xiě)入飘庄,不會(huì)覆蓋原文件內(nèi)容

②write():

fs = new FileOutputStream("文本文檔", true);
String str = "你好啊";
byte[] bytes = str.getBytes(); 將字符串轉(zhuǎn)換成byte數(shù)組
fs.write(bytes);
fs.flush();

③輸入輸出配合拷貝文件:

//創(chuàng)建一個(gè)輸入流對(duì)象
fis = new FileInputStream("C:\\Users\\Tong\\Desktop\\新建 文本文檔 (2).txt");
//創(chuàng)建一個(gè)輸出流對(duì)象
fos = new FileOutputStream("文本文檔", true);
            
byte[] bytes = new byte[1024*1024]; //一次最多拷貝1MB
int count = 0;
while((count = fis.read(bytes)) != -1){
    fos.write(bytes, 0, count);
}
fos.flush();
6、FileReader

①文件字符輸入流购撼,只能讀取普通文本
②read方法傳入的是char數(shù)組
③搭配Properties使用

//讀取xml配置文件
FileReader reader = new FileReader("xml");
Properties pro = new Properties(); //key value都是String
//將xml文件鍵值對(duì)加載到pro集合中
pro.load(reader);
//關(guān)閉流
reader.close();
//通過(guò)key獲取value
System.out.println(pro.getProperty("ClassName"));
7跪削、BufferedReader

①緩沖流自帶緩沖區(qū),不需要借用byte或者char數(shù)組
②構(gòu)造函數(shù):必須要傳入一個(gè)Reader對(duì)象

FileReader reader = new FileReader("C:\\Users\\Tong\\Desktop\\新建 文本文檔 (2).txt");
BufferedReader buf = new BufferedReader(reader);

③readLine()方法:讀取一行不帶換行符

8迂求、節(jié)點(diǎn)流和包裝流

①概念:
節(jié)點(diǎn)流:當(dāng)一個(gè)流的構(gòu)造方法中需要一個(gè)流的時(shí)候碾盐,這個(gè)被傳進(jìn)來(lái)的流叫做:節(jié)點(diǎn)流
包裝流:外部負(fù)責(zé)包裝的這個(gè)流叫做:包裝流/處理流
上例中FileReader 就是一個(gè)節(jié)點(diǎn)流;BufferedReader 就是包裝流(處理流)
處理結(jié)束之后只用關(guān)閉處理流(處理流中的close方法會(huì)關(guān)閉節(jié)點(diǎn)流)
②字節(jié)流轉(zhuǎn)換成字符流:
使用InputStreamReader揩局,構(gòu)造方法傳入FileInputStream字節(jié)流對(duì)象毫玖,返回一個(gè)Reader字符流對(duì)象

FileInputStream in = new FileInputStream("C:\\Users\\Tong\\Desktop\\新建 文本文檔 (2).txt");
buf = new BufferedReader(new InputStreamReader(in));
9、數(shù)據(jù)流

DataOutputStream數(shù)據(jù)專屬流:可以將數(shù)據(jù)連同數(shù)據(jù)類型一并寫(xiě)入文件
DataInputStream:DataOutputStream寫(xiě)的文件只能使用DataInputStream去讀凌盯,并且讀的順序需要與寫(xiě)的順序保持一致付枫,才可以正常取出數(shù)據(jù)。

10十气、標(biāo)準(zhǔn)輸出流PrintStream 【日志工具的實(shí)現(xiàn)】

①PrintStream對(duì)象:
PrintStream pr = System.out; 【System.out是一個(gè)PrintStream對(duì)象】
標(biāo)準(zhǔn)輸出流不需要手動(dòng)關(guān)閉
②修改流的輸出方向:
不再打印到控制臺(tái)励背,而是指向“l(fā)og”文件

PrintStream pr = new PrintStream(new FileOutputStream("log.txt"));
System.setOut(pr);  【修改輸出方向,將輸出方向修改到log文件】
11砸西、對(duì)象流

①序列化叶眉、反序列化
序列化:serialize,將java對(duì)象存儲(chǔ)到文件中芹枷,將java對(duì)象的狀態(tài)保存下來(lái)的過(guò)程衅疙;
反序列化:deserialize,將硬盤上的數(shù)據(jù)重新恢復(fù)到內(nèi)存中鸳慈,恢復(fù)成java對(duì)象饱溢;
②參與序列化、反序列化的對(duì)象走芋,必須實(shí)現(xiàn)Serializable接口
③Serializable接口只是一個(gè)標(biāo)志接口绩郎,接口里面什么代碼都沒(méi)有
④標(biāo)志接口:里面都是空的潘鲫,沒(méi)有代碼,作用是給類添加一個(gè)標(biāo)志肋杖,java虛擬機(jī)在看到標(biāo)志后會(huì)分別作出不同處理

十溉仑、File類

File f = new File("C:\Users\Tong\Desktop\新建 文本文檔 (2).txt");
f.exists() 文件是否存在
f.createNewFile(); 創(chuàng)建文件
f.mkdir(); 創(chuàng)建目錄
f.mkdirs(); 創(chuàng)建多重目錄
f.getParent(); 獲取文件的父路徑String
f.getParentFile(); 獲取文件的父親File對(duì)象
f.getAbsolutePath(); 獲取文件的絕對(duì)路徑
f.getName(); 獲取文件名
f.isDirectory(); 判斷是否是目錄
f.isFile(); 判斷是否是文件
f.lastModified(); 獲取最后一次修改的時(shí)間戳
f.length(); 獲取文件大小(單位是字節(jié))
f.listFiles(); 獲取當(dāng)前目錄下所有的子文件

十一状植、多線程

視頻鏈接:https://www.bilibili.com/video/BV1Rx411876f?p=796&vd_source=451d825d8e1ffcbfd124804db3810f11

1浊竟、同一進(jìn)程的線程共享【堆內(nèi)存】、【方法區(qū)內(nèi)存】津畸;【棧內(nèi)存】獨(dú)立
2振定、實(shí)現(xiàn)多線程的三種方法:

①編寫(xiě)一個(gè)類,直接繼承java.lang.Tread肉拓,重寫(xiě)run方法:

public class MyThread extends Thread{
    @Override
    public void run(){
        ...
    }
}

【如何使用】:在主函數(shù)中new出線程對(duì)象——>調(diào)用線程對(duì)象的start()方法

MyThread thread = new MyThread(); //創(chuàng)建線程對(duì)象
thread.start(); //啟動(dòng)線程

【start()方法的作用】:?jiǎn)?dòng)一個(gè)分支線程后频,在JVM中開(kāi)辟一個(gè)新的棧空間帝簇,只要椗枪空間開(kāi)出來(lái)靠益,start()方法就結(jié)束了丧肴,線程就啟動(dòng)成功了。啟動(dòng)成功的線程會(huì)自動(dòng)調(diào)用run方法胧后,并且將run方法壓入棧底部芋浮。
run方法在分支棧的棧底部,main方法在主棧的棧底部壳快,run和main是平級(jí)的纸巷。

②(使用較多)編寫(xiě)一個(gè)類,實(shí)現(xiàn)java.lang.Runnable接口眶痰,實(shí)現(xiàn)run方法:

public class MyThread implements Runnable{
    @Override
    public void run(){
        ...
    }
}

【如何使用】:在主函數(shù)中new出Thread對(duì)象瘤旨,構(gòu)造函數(shù)中傳入一個(gè)Runnable對(duì)象——>調(diào)用Thread對(duì)象的start()方法

Thread s = new Thread(new MyThread());  //創(chuàng)建線程對(duì)象
s.start();

③實(shí)現(xiàn)Callable接口:【可以獲取到線程的返回值】

package com.test.javase;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class Test {
    public static void main(String[] args) throws Exception{
        //使用匿名內(nèi)部類的方式實(shí)現(xiàn)Callable接口
        FutureTask task = new FutureTask(new Callable() {
            //call()方法相當(dāng)于run()方法
            public Object call() throws Exception {
                Thread.sleep(1000);
                int a = 3;
                int b = 4;
                return a + b;
            }
            
        });
        
        //創(chuàng)建線程對(duì)象
        Thread t = new Thread(task);
        t.start();
        
        //獲取到t線程的返回值
        System.out.println(task.get());  //會(huì)阻塞當(dāng)前線程,因?yàn)橹挥挟?dāng)t線程執(zhí)行完才能夠拿到返回值
        
        System.out.println(Thread.currentThread().getName());
    }
}
3竖伯、線程生命周期:

start方法執(zhí)行完畢之后存哲,線程進(jìn)入就緒態(tài),開(kāi)始爭(zhēng)奪CPU時(shí)間片
JVM調(diào)度分配時(shí)間片
當(dāng)run方法使用完一個(gè)時(shí)間片后七婴,線程又進(jìn)入就緒態(tài)祟偷,等待JVM調(diào)度
當(dāng)run方法結(jié)束后進(jìn)入死亡狀態(tài)

4、線程對(duì)象的方法:
  • setName("Thread-0") 設(shè)置線程名打厘;
  • getName() 獲取線程名修肠;
  • Thread.currentThread() 獲取當(dāng)前線程對(duì)象,這個(gè)方法出現(xiàn)在哪個(gè)線程的代碼中户盯,返回的就是哪個(gè)線程嵌施,類似于this饲化;
  • Thread.sleep(1000L) 接收l(shuí)ong參數(shù),表示毫秒數(shù)吗伤;讓當(dāng)前線程進(jìn)入休眠(阻塞態(tài))滓侍,出現(xiàn)在哪個(gè)線程中,哪個(gè)線程就進(jìn)入休眠牲芋;
  • interrupt() 中斷線程的休眠撩笆,喚醒線程(這種終斷睡眠的方式依靠了java的異常處理機(jī)制),會(huì)進(jìn)入sleep的catch語(yǔ)句塊中
  • stop() 強(qiáng)制終止線程執(zhí)行缸浦,可能會(huì)導(dǎo)致丟失數(shù)據(jù)夕冲,不建議使用
  • 合理結(jié)束線程:
package com.test.javase;

public class Test {
    public static void main(String[] args) throws Exception{
        MyThread t = new MyThread();
        Thread s = new Thread(t);
        s.start();
        
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
        
        t.run = false; 手動(dòng)結(jié)束線程
    }
}

class MyThread implements Runnable{
    boolean run = true;
    
    @Override
    public void run(){
        for(int i = 0; i < 10; i++){
            if(run){
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }else{
                  return就結(jié)束了,在結(jié)束前可以保存未保存的值
                //終止當(dāng)前線程
                return;
            }
        }
    }
}

  • setPriority() 設(shè)置線程優(yōu)先級(jí)裂逐,最高10歹鱼,最低1,默認(rèn)5卜高;
  • getPriority() 獲取線程優(yōu)先級(jí)弥姻;
  • Thread.yield() 暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程掺涛,會(huì)讓當(dāng)前進(jìn)程從運(yùn)行態(tài)進(jìn)入就緒態(tài)庭敦;
  • t.join() 合并線程,當(dāng)前線程進(jìn)入阻塞薪缆,t線程執(zhí)行秧廉,直到t線程結(jié)束,當(dāng)前線程才可以繼續(xù)執(zhí)行拣帽;
  • Thread.currentThread().getContextClassLoader().getResource("xml.txt").getPath() 獲取類路徑下xml.txt文件的絕對(duì)路徑
5疼电、java線程調(diào)度

java線程調(diào)度策略采用的是【優(yōu)先級(jí)搶占式調(diào)度】

6、線程安全

①java中保證線程安全的關(guān)鍵是使用【線程同步】

②局部變量永遠(yuǎn)不會(huì)存在線程安全的問(wèn)題减拭,因?yàn)榫植孔兞吭跅V胁还蚕肀尾颍粋€(gè)線程一個(gè)棧;實(shí)例變量(在堆中)和靜態(tài)變量(在方法區(qū))可能存在線程安全

③synchronized:

synchronized的用法:

synchronized (XX) {
   ...
}

假設(shè)有[t1拧粪、t2修陡、t3、t4既们、t5]幾個(gè)線程濒析,此時(shí)希望t1、t2啥纸、t5同步進(jìn)行某項(xiàng)操作号杏,這時(shí)XX傳入的就是t1、t2、t5共享的一個(gè)對(duì)象盾致,希望同步執(zhí)行的代碼塊寫(xiě)入synchronized中主经,執(zhí)行時(shí)java會(huì)給該對(duì)象加對(duì)象鎖(只支持獨(dú)占式訪問(wèn))

  • 同步的代碼塊越少,效率越高
  • synchronized出現(xiàn)在實(shí)例方法上作為修飾關(guān)鍵字時(shí)庭惜,一定鎖的是this(括號(hào)中傳入的對(duì)象是this)罩驻,不能修改,所以這種方式不靈活护赊。同時(shí)整個(gè)方法體都需要同步惠遏,可能會(huì)無(wú)故擴(kuò)大同步范圍,導(dǎo)致程序的執(zhí)行效率降低骏啰。如果共享的對(duì)象就是this节吮,并且需要同步的代碼塊是整個(gè)方法體,建議使用這種方式判耕。

④synchronized的寫(xiě)法:

  • 同步代碼塊
public void test(){
    ...
    synchronized (XX) {
        需要同步的代碼塊...
    }
    ...
}
  • 作為修飾關(guān)鍵字
public synchronized void test(){
    需要同步的代碼塊...
}
  • 在靜態(tài)方法上使用synchronized:
    表示找類鎖透绩,類鎖永遠(yuǎn)只有一把,就算創(chuàng)建多個(gè)對(duì)象壁熄,類鎖也只有一把帚豪。
    對(duì)象鎖:1個(gè)對(duì)象1把鎖
    類鎖:類鎖只有一把,用于保證靜態(tài)變量的安全
public synchronized static void test(){
    需要同步的代碼塊...
}

⑤死鎖:synchronized最好不要嵌套使用草丧,可能會(huì)引起死鎖
死鎖例子:

public class Test {
    public static void main(String[] args) throws Exception{
        Object o1 = new Object();
        Object o2 = new Object();
        
        MyThread1 t1 = new MyThread1(o1, o2);
        MyThread2 t2 = new MyThread2(o1, o2);
        
        t1.start();
        t2.start();
    }
}

class MyThread1 extends Thread{
    Object o1;
    Object o2;
    public MyThread1(Object o1, Object o2) {
        super();
        this.o1 = o1;
        this.o2 = o2;
    }
    
    public void run(){
        synchronized (o1) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (o2) {
                
            }
        }
    }
}

class MyThread2 extends Thread{
    Object o1;
    Object o2;
    public MyThread2(Object o1, Object o2) {
        super();
        this.o1 = o1;
        this.o2 = o2;
    }
    
    public void run(){
        synchronized (o2) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (o1) {
                
            }
        }
    }
}
7狸臣、守護(hù)線程

①概念:

  • java中線程分為兩大類:用戶線程、守護(hù)線程(后臺(tái)線程)
  • 垃圾回收線程就是一個(gè)守護(hù)線程方仿,main方法是一個(gè)用戶線程固棚;
  • 特點(diǎn):守護(hù)線程一般是一個(gè)死循環(huán),所有的用戶線程結(jié)束仙蚜,守護(hù)線程會(huì)自動(dòng)結(jié)束
  • t.setDaemon(true):將一個(gè)用戶線程設(shè)置為守護(hù)線程

②定時(shí)器:
實(shí)現(xiàn)方式:

  • 可以使用sleep方法,設(shè)置睡眠時(shí)間厂汗,每到這個(gè)時(shí)間點(diǎn)醒來(lái)委粉,執(zhí)行任務(wù)。這種方法是最原始的定時(shí)器娶桦;
  • 在java類庫(kù)中已經(jīng)寫(xiě)好了一個(gè)定時(shí)器贾节,java.util.Timer呛梆,可以直接使用锡搜;
  • 實(shí)際開(kāi)發(fā)中使用較多的是Spring框架中提供的SpringTask框架,這個(gè)框架只需要簡(jiǎn)單的配置就可以完成定時(shí)器的任務(wù)丹拯。
8祈争、wait斤程、notify方法
  • wait、notify方法不是線程對(duì)象的方法菩混,是java對(duì)象都有的方法忿墅;
  • wait扁藕、notify方法都建立在線程同步的基礎(chǔ)上,因?yàn)槎嗑€程要同時(shí)操作一個(gè)倉(cāng)庫(kù)疚脐,存在線程安全問(wèn)題亿柑;
  • o.wait()方法讓正在o對(duì)象上活動(dòng)的線程t進(jìn)入等待狀態(tài),并且釋放t線程之前占有的o對(duì)象的鎖棍弄;
  • 生產(chǎn)者望薄、消費(fèi)者模式:
package com.test.javase;

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

public class Test {
    public static void main(String[] args) throws Exception{
        List list = new ArrayList<Object>();
        
        Thread t1 = new Thread(new Producer(list));
        Thread t2 = new Thread(new Customer(list));
        
        t1.start();
        t2.start();
    }
}

class Producer implements Runnable{
    List list;

    public Producer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while(true){
            synchronized (list) {
                if(list.size() > 0){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                list.add(new Object());
                System.out.println("生產(chǎn)者生產(chǎn)了:"+list.get(0));
                list.notify();
            }
        }
    }
}

class Customer implements Runnable{
    List list;

    public Customer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while(true){
            synchronized (list) {
                if(list.size() == 0){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Object obj = list.remove(0);
                System.out.println("消費(fèi)者消費(fèi)了:"+obj);
                list.notify();
            }
        }
    }
}

十二、反射機(jī)制

視頻鏈接:https://www.bilibili.com/video/BV1Rx411876f?p=810

1呼畸、基礎(chǔ)概念
  • 通過(guò)反射機(jī)制可以操作字節(jié)碼文件
  • 通過(guò)使用反射機(jī)制可以直接用類名創(chuàng)建對(duì)象式矫,使程序變得更加靈活
  • 反射機(jī)制的相關(guān)類在 java.lang.reflect.* 包下
  • 反射機(jī)制相關(guān)的重要類:
    java.lang.Class; 代表整個(gè)字節(jié)碼,整個(gè)類
    java.lang.reflect.Method; 代表字節(jié)碼中的方法字節(jié)碼役耕。代表類中的方法
    java.lang.reflect.Constructor; 代表字節(jié)碼中的構(gòu)造方法字節(jié)碼采转。代表類中的構(gòu)造函數(shù)
    java.lang.reflect.Field; 代表字節(jié)碼中的屬性字節(jié)碼。代表類中的成員變量
  • 如果只希望一個(gè)類的靜態(tài)代碼塊執(zhí)行瞬痘,其他代碼一律不執(zhí)行故慈,可以使用:
    Class.forName("完整類名");
    這個(gè)方法的執(zhí)行會(huì)導(dǎo)致類加載,類加載時(shí)框全,靜態(tài)代碼塊執(zhí)行察绷。
2、獲取Class的三種方式
  • Class.forName("完整類名");
    Class c = Class.forName("java.lang.String");
  • 對(duì)象.getClass();
    String s = "abc";
    Class c = s.getClass();
  • 類.class;
    Class c = String.class;
3津辩、通過(guò)讀屬性文件實(shí)例化對(duì)象
//獲取絕對(duì)路徑的方式
//String path = Thread.currentThread().getContextClassLoader().getResource("xml").getPath()
//FileReader reader = new FileReader(path);
        
//直接以流的形式返回
InputStream reader = Thread.currentThread().getContextClassLoader().getResourceAsStream("xml");
Properties pro = new Properties(); //key value都是String
//將xml文件鍵值對(duì)加載到pro集合中
pro.load(reader);
//關(guān)閉流
reader.close();
//通過(guò)key獲取value
Class a = Class.forName(pro.getProperty("ClassName"));
//實(shí)例化對(duì)象     
Object obj = a.newInstance();
4拆撼、資源綁定器
  • java.util包下提供了一個(gè)資源綁定器,便于獲取【屬性配置文件】中的內(nèi)容喘沿;
  • 資源綁定器只能綁定xxx.properties文件闸度,且該文件必須在類路徑下(bin或者src文件夾中);
  • 在寫(xiě)路徑的時(shí)候蚜印,文件名不需要帶擴(kuò)展名莺禁;
  • 例如:
ResourceBundle bundle = ResourceBundle.getBundle("xml");
String className = bundle.getString("ClassName");
System.out.println(className);
5、反射屬性Field
  • ①獲取類的屬性Field:
Class studentClass = Student.class;
//只能獲取public修飾的field
Field[] fields = studentClass.getFields();
for(Field f : fields){
    System.out.println(f.getName());
}
        
//獲取所有的field
Field[] allFields = studentClass.getDeclaredFields();
for(Field f : allFields){
    System.out.println("屬性名:"+f.getName());
    System.out.println("類型:"+f.getType().getSimpleName());
    System.out.println("修飾符:"+Modifier.toString(f.getModifiers()));
    System.out.println("---------");
}
  • ②反編譯:
    可以通過(guò)class文件反編譯出它含有的屬性窄赋、方法等
  • ③通過(guò)反射機(jī)制訪問(wèn)對(duì)象屬性(賦值哟冬、取值):
Class studentClass = Student.class;
Object obj = studentClass.newInstance();
Field id = studentClass.getDeclaredField("id");
id.set(obj, "123k"); //給obj對(duì)象的id屬性賦值
System.out.println(id.get(obj)); //取出obj對(duì)象的id屬性值
  • ④訪問(wèn)private私有變量:age.setAccessible(true);打破封裝
Field age = studentClass.getDeclaredField("age");
age.setAccessible(true);
age.set(obj, 12);
System.out.println(age.get(obj));
6、反射Method

①反編譯Method:

public static void main(String[] args) throws Exception{
    Class studentClass = Student.class;
        
    Method[] methods = studentClass.getDeclaredMethods();
        
    for(Method m : methods){
        System.out.println("修飾符:" + Modifier.toString(m.getModifiers()));
            
        System.out.println("返回類型:" + m.getReturnType().getSimpleName());
            
        System.out.println("方法名:" + m.getName());
            
        StringBuffer s = new StringBuffer();

        Class[] parameterTypes = m.getParameterTypes();
        for(Class parameterType : parameterTypes){
            s.append(parameterType.getSimpleName() + " ");
        }
        System.out.println("參數(shù)類型列表:" + s);
        
        System.out.println();
    }
}

②反射機(jī)制調(diào)用方法:【*******五顆星重點(diǎn)*******】
視頻鏈接:https://www.bilibili.com/video/BV1Rx411876f?p=830&vd_source=451d825d8e1ffcbfd124804db3810f11

原類中的方法:

public int test2(int i, Boolean b){
    System.out.println("測(cè)試方法2");
    if(b) return 1;
    return 0;
}

反射機(jī)制調(diào)用test2方法:

//獲得class
Class studentClass = Student.class;

//實(shí)例化對(duì)象
Object obj = studentClass.newInstance(); 

//反射Method:傳入方法名忆绰、方法參數(shù)類型浩峡,用以區(qū)分【方法重載】
Method method = studentClass.getDeclaredMethod("test2", int.class, Boolean.class);

反射機(jī)制調(diào)用方法
/*四要素:
method方法、
obj對(duì)象错敢、
1, true 實(shí)參
res返回值
*/
Object res = method.invoke(obj, 1, true);
        
System.out.println(res);
7翰灾、反射Constructor

反射機(jī)制調(diào)用構(gòu)造方法:
先獲取到有參數(shù)的構(gòu)造方法,調(diào)用構(gòu)造方法new對(duì)象

public static void main(String[] args) throws Exception{
    Class studentClass = Student.class;
        
    //無(wú)參數(shù)構(gòu)造函數(shù)
    Object obj = studentClass.newInstance();
    
    //獲取到帶參數(shù)構(gòu)造方法
    Constructor con = studentClass.getDeclaredConstructor(String.class, String.class, int.class);
    //使用該構(gòu)造方法new對(duì)象
    Object newObj = con.newInstance("1120abc", "laowang", 23);
    System.out.println(newObj.toString());
}
8、獲取父類和父接口
public static void main(String[] args) throws Exception{
    Class studentClass = Student.class;
        
    //獲取繼承的父接口
    Class[] interfaces = studentClass.getInterfaces();
    for(Class i : interfaces){
        System.out.println(i.getSimpleName());
    }
        
    //獲取父類
    Class superClass = studentClass.getSuperclass();
    
    System.out.println(superClass.getSimpleName());
}

十三预侯、注解

①基礎(chǔ)概念:
注解Annotation是一種引用數(shù)據(jù)類型致开,編譯之后也是生成xxx.class文件;

②自定義注解:
[修飾符列表] @interface 注解類型名{
}
例如:

public @interface MyAnnotation {

}

③使用注解:
@注解名
注解可以出現(xiàn)在類上萎馅、屬性上双戳、方法上、變量上糜芳、注解上......

④JDK內(nèi)置的注解:

  • @Deprecated:表示標(biāo)注的這個(gè)類飒货、方法等已過(guò)時(shí)
  • @Override:只能注解方法。是給編譯器參考的峭竣,跟運(yùn)行階段沒(méi)關(guān)系塘辅;凡是java方法中帶有這個(gè)注釋的,編譯器都會(huì)進(jìn)行編譯檢查皆撩,如果這個(gè)方法不是重寫(xiě)父類的方法扣墩,編譯器會(huì)報(bào)錯(cuò)。

⑤元注解:
修飾注解的注解稱為元注解扛吞,例如:

  • Target:用來(lái)標(biāo)注“被標(biāo)注的注解”可以出現(xiàn)在哪些位置上呻惕;
    @Target(ElementType.METHOD):表示該注解只能出現(xiàn)在方法上;
  • Retention:用來(lái)標(biāo)注“被標(biāo)注的注解”最終保存在哪里滥比;
    @Retention(RetentionPolicy.SOURCE):表示該注解只被保留在java源文件中亚脆;
    @Retention(RetentionPolicy.CLASS):表示該注解被保存在calss文件中;
    @Retention(RetentionPolicy.RUNTIME):表示該注解被保存在calss文件中盲泛,并且可以被反射機(jī)制讀取濒持。

⑥注解中定義屬性:

  • 語(yǔ)法:
public @interface MyAnnotation {
    //name屬性
    String name();
    int age() default 25; //指定默認(rèn)值
}
  • 如果一個(gè)注解當(dāng)中有屬性,那么使用該注解時(shí)一定要給屬性賦值寺滚,除非有默認(rèn)值:
    @MyAnnotation(屬性名=屬性值)

  • 如果屬性名是“value”并且只有一個(gè)屬性柑营,使用注解時(shí),屬性名可以省略:
    定義:String value();
    使用:@MyAnnotation("hello")

  • 注解中屬性允許的類型:
    byte short int long float double boolean char String Class 枚舉
    以及以上每一種的數(shù)組形式

⑦反射注解:

  • 被反射的注解必須要被保存在class文件中玛迄,要能被反射機(jī)制讀取由境,即:
    @Retention(RetentionPolicy.RUNTIME)

  • 反射機(jī)制獲取到注解對(duì)象的屬性:

Class stuClass = Student.class;
if(stuClass.isAnnotationPresent(MyAnnotation.class)){ //判斷是否存在該注解
    MyAnnotation myAnnotation = (MyAnnotation)stuClass.getAnnotation(MyAnnotation.class);
    System.out.println(myAnnotation.age());
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蓖议,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌讥蟆,老刑警劉巖勒虾,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異瘸彤,居然都是意外死亡修然,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)愕宋,“玉大人玻靡,你說(shuō)我怎么就攤上這事≈斜矗” “怎么了囤捻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)邻寿。 經(jīng)常有香客問(wèn)我蝎土,道長(zhǎng),這世上最難降的妖魔是什么绣否? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任誊涯,我火速辦了婚禮,結(jié)果婚禮上蒜撮,老公的妹妹穿的比我還像新娘暴构。我一直安慰自己,他們只是感情好段磨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布取逾。 她就那樣靜靜地躺著,像睡著了一般薇溃。 火紅的嫁衣襯著肌膚如雪菌赖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天沐序,我揣著相機(jī)與錄音琉用,去河邊找鬼。 笑死策幼,一個(gè)胖子當(dāng)著我的面吹牛邑时,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播特姐,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晶丘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了唐含?” 一聲冷哼從身側(cè)響起浅浮,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捷枯,沒(méi)想到半個(gè)月后滚秩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淮捆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年郁油,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了本股。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桐腌,死狀恐怖拄显,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情案站,我是刑警寧澤躬审,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嚼吞,受9級(jí)特大地震影響盒件,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舱禽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一炒刁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧誊稚,春花似錦翔始、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至疾瓮,卻和暖如春脖镀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狼电。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蜒灰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肩碟。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓强窖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親削祈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子翅溺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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