Java基礎(chǔ)知識
一、java概述
起源
- 1990年,Sun公司的James Gosling(Java之父)研發(fā)名為Oak的語言(Java的前身),1994年,Oak被正式更名為Java。
語言優(yōu)勢
- 簡單:語法風(fēng)格與C++類似,但是沒有指針、多繼承(Java中只允許單繼承),有自動回收機(jī)制,而且有大量的類庫。
- 完全面向?qū)ο螅篔ava是一種完全面向?qū)ο蟮恼Z言。
- 分布式:提供對多種網(wǎng)絡(luò)協(xié)議的支持。
- 安全可靠:不支持指針,沒有非法訪問、內(nèi)存泄漏,有垃圾回收機(jī)制,編譯器會檢查程序,而且有異常處理機(jī)制。
- 跨平臺:只要安裝了Java運(yùn)行時(shí)系統(tǒng),可以在任意的處理器運(yùn)行。
- 解釋執(zhí)行:Java的源文件即.java文件首先被編譯為.class文件,再通過JVM解釋執(zhí)行。
- 多線程。
- 動態(tài):Java類庫中可以自由地加入內(nèi)容。
二、注釋
單行注釋 // 文檔注釋 /** / 多行文檔 /*/
三、基本數(shù)據(jù)類型
| 數(shù)據(jù)類型 | 字節(jié)數(shù) | 位數(shù) | 默認(rèn)值 | 注釋 |
|---|---|---|---|---|
| byte(字節(jié)) | 1 | 8 | 0 | |
| short(短整型) | 2 | 16 | 0 | |
| int(整型) | 4 | 32 | 0 | |
| long(長整型) | 8 | 64 | 0 | 結(jié)尾跟L,l |
| float(單精度) | 4 | 32 | 0.0 | 結(jié)尾跟F,f |
| double(雙精度) | 8 | 64 | 0.0 | |
| char(字符型) | 2 | 16 | 空格 | |
| boolean(布爾型) | false |
1.字符類型(char)
char可以與整數(shù)做運(yùn)算。 例:char ch = 'a'; 和 char ch = 97;
| 轉(zhuǎn)義字符 | 意義 |
|---|---|
| \ddd | 1到3位八進(jìn)制數(shù)據(jù)所表示的字符 |
| \uxxxx | 4位十六進(jìn)制所表示的字符 |
| \r | 回車 |
| \n | 換行 |
| \b | 退格 |
| \f | 換頁 |
| \t | 垂直制作表光標(biāo)移動到下一行 |
| \'、\" | '、" |
| \\ | \ |
四、數(shù)據(jù)類型轉(zhuǎn)換
隱式轉(zhuǎn)換:
自動轉(zhuǎn)換兼容順序:
- byte-->short-->int-->long-->float-->double
- 特殊:char與部分int型數(shù)字兼容
顯示轉(zhuǎn)換:
(int)1.0;
五、運(yùn)算符
1.位邏輯運(yùn)算符
&與(面試題11) |或 ~a取反 ^a異或 <<左移位(面試題12) >>右移位 >>>無符號右移位
2.復(fù)合賦值運(yùn)算符
+=、-=、*=、/=、>>=、<<=、>>>=
3.三元運(yùn)算符
條件表達(dá)式?值1:值2 其等價(jià)于if...else語句
4.運(yùn)算符優(yōu)先級
- 括號()
- 正負(fù)號+,-
- 一元運(yùn)算符++,--,!
- 乘除*,/
- 加減+,-
- 移位運(yùn)算>>,>>>,<<
- 比較大小<,>,>=,<=
- 比較是否相等 ==,!=
- 位與運(yùn)算 &
- 位異或運(yùn)算 ^
- 位或運(yùn)算 |
- 邏輯與運(yùn)算 &&
- 邏輯或運(yùn)算 ||
- 三元運(yùn)算 ?:
- 賦值運(yùn)算符 =
六、java關(guān)鍵字
- java關(guān)鍵字都是小寫的
- Java語言一共使用了48個(gè)保留關(guān)鍵字,他們主要可以
分為如下幾類:
訪問控制
- private 私有,
- protected 保護(hù),
- public 共享.
類、方法和變量修飾符
- abstract 摘要,
- class 類,
- extends 擴(kuò)允,
- final 結(jié)局,
- implements 工具,
- interface 接口,
- native 本地,
- new 新,
- static 靜態(tài),
- synchronized 同步,
- transient 短暫,
- volatile 易失.
程序控制語句
- break,
- continue,
- return,
- do,
- while,
- if,
- else,
- for,
- instanceof,
- switch,
- case,
- default,
錯(cuò)誤處理
- catch 捕獲,
- finally 最后,
- throw 投試,
- throws 投試,
- try嘗試.
+包相關(guān)
- import 輸入,
- package 包.
基本類型
- boolean 布爾型,
- byte 字節(jié)型,
- char 字符型,
- double 雙精度,
- float 浮點(diǎn),
- int 整型,
- long 長整型,
- short短整型.
變量引用
- super 特殊,
- this 這個(gè),
- void無值.
除了這48個(gè)關(guān)鍵字以外,還有3個(gè)語法保留字:
- null 空,
- true 真,
- false 假.
七、分支語句
if
if (布爾表達(dá)式) {
} else {
}
布爾表達(dá)式:最后返回的結(jié)果必須是一個(gè)布爾值??梢允且粋€(gè)單純的布爾變量或常量,也可以是關(guān)系表達(dá)式。
if (布爾表達(dá)式) {
語句1
} else if (布爾表達(dá)式) {
語句2
} else {
語句3
}
switch
switch(用于判斷的參數(shù)) {
case 常量表達(dá)式1 : 語句1;[break;]
case 常量表達(dá)式2 : 語句2;[break;]
.......
[default : 常量表達(dá)式n : 語句n;[break;]]
}
switch多分枝語句中 常量表達(dá)式必須是六種類型:byte、short、char、int4種整形類型以及String字符類,枚舉類型。不可以時(shí)long類型。
default可以不寫,如果case都不滿足則不做處理。
八、循環(huán)語句
while
while(){
}
do while
do {
} while();
for
for(表達(dá)式1;表達(dá)式2;表達(dá)式3) {
}
foreach(增強(qiáng)循環(huán))
for(循環(huán)變量x :遍歷對象obj) {
引用x的java語句
}
在遍歷數(shù)組方面更加方便。
遍歷二維數(shù)組
for(int[] row :Array){
for(int data :row) {
}
}
九、跳轉(zhuǎn)語句
- break; 跳出循環(huán)
- continue; 跳出此次循環(huán),進(jìn)入下一次循環(huán)
十、數(shù)組
動態(tài)初始化:
- 只指定數(shù)組長度,由系統(tǒng)為數(shù)組分配初始值
- 格式:數(shù)據(jù)類型[] 變量名 = new 數(shù)據(jù)類型[數(shù)組長度];
- 注意:堆內(nèi)存,棧內(nèi)存,內(nèi)存分配問題
- 例:int[] arr = new arr[2];
靜態(tài)初始化:
- 初始化時(shí)指定每個(gè)數(shù)組元素的初始值,由系統(tǒng)決定數(shù)組長度
- 格式:數(shù)據(jù)類型[] 變量名 = new 數(shù)據(jù)類型[]{數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,.......};
- 簡化格式:數(shù)據(jù)類型[] 變量名 = {數(shù)據(jù)1,數(shù)據(jù)2,......}
- 例:int[] arr = new int{1, 2, 3, 4, 5};或int[] arr = {1, 2, 3, 4, 5};
一維數(shù)組:
//申明
int a[];
int[] a; //引用
//申明并分配內(nèi)存空間
int a[] = new int[5];
//申明,分配內(nèi)存空間,賦值
int a[] = { 1, 2, 3 };
int b[] = new int[] { 4, 5, 6 };
int c[] = new int[3];
二維數(shù)組:
//聲明
int tdarr[][];
char[][] tdarr2;
//分配內(nèi)存兩種方式
int a[][] = new int[2][4];
int b[][]; //這種方法可以形成不規(guī)則數(shù)組
b = new int[2][]; //先分配行,再分配列,不能先分配列
b[0] = new int[3]; //給第一行分配列
b[1] = new int[2]; //給第二行分配列,
//三種數(shù)值賦值
//前兩種類似與一維
//后一種為每一行賦值
int tdarr[][] = new int[2][3];
tdarr[0] = new int[]{1, 2, 3};
Array.fill(int[] a, int value) //用value填滿數(shù)組
十一、String類
字符串默認(rèn)值為null,如果此時(shí)調(diào)用String的方法會出現(xiàn)空指針異常。
兩種創(chuàng)建方式的區(qū)別:
1.String str = “123456”;(推薦)
方便,且可以實(shí)現(xiàn)棧內(nèi)存共享堆內(nèi)存中的字符串,因?yàn)椤?23456”會存放在對內(nèi)存的字符串池中,在次指向它是不會再創(chuàng)建新的堆內(nèi)存,而是直接指向它。(池?cái)?shù)據(jù)的自動保存,以進(jìn)行重用)
String strA = "123456"; - String strB = "123456"; //strA,strB指向相同的堆內(nèi)存 //strA == strB為true-
字符串常量(對象)池
- 目的:實(shí)現(xiàn)共享處理
- 靜態(tài)常量池,指程序(*.class)在加載的時(shí)候,對自動將此程序之中保存的字符串,普通的常量,類和方法 的信息等,全都進(jìn)行分配。
- 運(yùn)行時(shí)常量池,當(dāng)加載之后,存在一些變量,這個(gè)時(shí)候提供的是與與運(yùn)行時(shí)常量值。
2.String str = new String("123456"); (構(gòu)造方法實(shí)例化)
- 會產(chǎn)生兩塊堆內(nèi)存空間,其中一塊會變?yōu)槔臻g,“123456”先創(chuàng)建一份空間,new的時(shí)候再次創(chuàng)建一個(gè)空間
- public String intern(); //手動入池。
字符串“常量”
String str = "String";
“String”其實(shí)是是匿名對象
開發(fā)過程中在利用equals();要把字符串常量放在前面,這樣避免空指針異常
常用方法
a.concat(str); //拼接字符串
str.length(); //字符串長度
str.charAt(index);//獲取指定索引的字符
//substr在a中首次出現(xiàn)的位置,若沒有則為-1。查找字符串中是否有某個(gè)字符。
a.indexOf(sybstr);
//str:任意字符串。prefix:作為前(后)綴的字符串。
str.startsWith(fix);
str.endsWith(fix);
//將字符串轉(zhuǎn)換為一個(gè)字符數(shù)組
str.toCharArray();
//子字符串是否存在,返回布爾類型
str.contains(string);
//beginIndex:起始索引(包括)。 //endIndex:結(jié)束索引(不包括)。
str.substring(beginIndex); str.substring(beginIndex,endIndex);
//替換所有的oldstr為newstr
str.replace(oldstr, newstr);
char[] charArray ={'時(shí)','間','就','是','金','錢'};
String a = new String(charArray, 3, 2); //從第四個(gè)開始提兩個(gè)
//分隔符表達(dá)式
str.split(regex);(源碼)
//轉(zhuǎn)換為小(大)寫
str.toLowerCase();
str.toUpperCase();
//去除首位空格
str.trim();
//判斷字符串是否相等
a.equals(str);
十二、可變字符串
StringBuffer類
創(chuàng)建方法
StringBuffer sbf = new StringBuffer();
StringBuffer sbf = new StringBuffer("abc");
StringBuffer sbf = new StringBuffer(32); //創(chuàng)建一個(gè)對象,初始容量為32個(gè)字符。
常用方法
//參數(shù)換成字符串,追加到此序列。 obj,可以是任意數(shù)據(jù)類型。
sbf.append(obj);
//index被替換字符的索引 ch替換后的字符。
sbf.setCharAt(index, ch);
//插入的索引,插入的字符串。
sbf.inset(offset, str);
//刪除字符串,起始索引包括,結(jié)束索引不包括。
sbf.delete(start, end);
//提取索引處的字符
sbf.charAt(int);
sbf.reverse();//反轉(zhuǎn)字符串
sbf.replace(3,4,"new");//替換從3開始4結(jié)束
StringBulider類
內(nèi)容可變,性能比Stringbuffer高但不適合多線程。
十三、常量與變量
2.java中的變量包括 成員變量 和 局部變量 。
成員變量:
1.直接定義在類中,方法外面。又稱之為字段(Field),不要稱之為屬性(錯(cuò)誤) 2.聲明后,不論是否初始化,JVM都會將其初始化為默認(rèn)值。
局部變量:
1.除了成員變量,其他都是局部變量,具體存在于下面三個(gè)地方
1)方法內(nèi)
2)方法的形參
3)代碼塊中(一對花括號)
2.必須初始化
常量:
- java中用final定義常量,且用習(xí)慣用大寫字母
- 將一些具有特殊含義的值設(shè)為常量可以增加代碼的可讀性
難點(diǎn)/面試題
1.關(guān)鍵字問題(見上文)
2.java中的變量包括 成員變量 和 局部變量 (特點(diǎn))。(見上文)
3.boolean默認(rèn)值為false
4.String的默認(rèn)值為null
5.String類的幾個(gè)方法使用 (見上文)
6.equals與==的區(qū)別
對于基本類型和引用類型 == 的作用效果是不同的,如下所示:
- 基本類型:比較的是值是否相同;
- 引用類型:比較的是引用是否相同;
equals 本質(zhì)上就是 ==,只不過 String 和 Integer 等重寫了 equals 方法,把它變成了值比較。對于自定義的類建議重寫equals方法。
7.jdk和jre的區(qū)別
- JDK:Java Development Kit 的簡稱,java 開發(fā)工具包,提供了 java 的開發(fā)環(huán)境和運(yùn)行環(huán)境。
- JRE:Java Runtime Environment 的簡稱,java 運(yùn)行環(huán)境,為 java 的運(yùn)行提供了所需環(huán)境。
具體來說 JDK 其實(shí)包含了 JRE,同時(shí)還包含了編譯 java 源碼的編譯器 javac,還包含了很多 java 程序調(diào)試和分析的工具。簡單來說:如果你需要運(yùn)行 java 程序,只需安裝 JRE 就可以了,如果你需要編寫 java 程序,需要安裝 JDK。
8.final 在 java 中有什么作用?
- final 修飾的類叫最終類,該類不能被繼承。
- final 修飾的方法不能被重寫。
- final 修飾的變量叫常量,常量必須初始化,初始化之后值就不能被修改。
9.java 中操作字符串都有哪些類?它們之間有什么區(qū)別?
操作字符串的類有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的區(qū)別在于 String 聲明的是不可變的對象,每次操作都會生成新的 String 對象,然后將指針指向新的 String 對象,而 StringBuffer、StringBuilder 可以在原有對象的基礎(chǔ)上進(jìn)行操作,所以在經(jīng)常改變字符串內(nèi)容的情況下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的區(qū)別在于,StringBuffer 是線程安全的,而 StringBuilder 是非線程安全的,但 StringBuilder 的性能卻高于 StringBuffer,所以在單線程環(huán)境下推薦使用 StringBuilder,多線程環(huán)境下推薦使用 StringBuffer。
10.String 屬于基礎(chǔ)的數(shù)據(jù)類型嗎?
String 不屬于基礎(chǔ)類型,基礎(chǔ)類型有 8 種:byte、boolean、char、short、int、float、long、double,而 String 屬于對象。
11.請簡述String兩種創(chuàng)建方式的區(qū)別?
只創(chuàng)建了一個(gè)實(shí)例化對象,并會自動給進(jìn)入字符串池,可以實(shí)現(xiàn)實(shí)例化對象的重用
會創(chuàng)建兩個(gè)實(shí)例化對象,而且不能自動入池,不過可以通過intern()方法,手動入池。
String str = null;和String str = "";是兩個(gè)不同的概念。 ""是一個(gè)字符串
11、&和&&的區(qū)別?
&運(yùn)算符有兩種用法:(1)按位與;(2)邏輯與。&&運(yùn)算符是短路與運(yùn)算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運(yùn)算符左右兩端的布爾值都是true 整個(gè)表達(dá)式的值才是 true。&&之所以稱為短路運(yùn)算是因?yàn)?,如?amp;&左邊的表達(dá)式的值是 false,右邊的表達(dá)式會被直接短路掉,不會進(jìn)行運(yùn)算。很多時(shí)候我們可能都需要用&&而不是&,例如在驗(yàn)證用戶登錄時(shí)判定用戶名不是 null 而且不是空字符串,應(yīng)當(dāng)寫為:username != null &&!username.equals(“”),二者的順序不能交換,更不能用&運(yùn)算符,因?yàn)榈谝粋€(gè)條件如果不成立,根本不能進(jìn)行字符串的 equals 比較,否則會生 NullPointerException 異常。注意:邏輯或運(yùn)算符(|)和短路或運(yùn)算符(||)的差別也是如此。
12、用最有效率的方法計(jì)算 2 乘以 8?
2 << 3(左移 3 位相當(dāng)于乘以 2 的 3 次方,右移 3 位相當(dāng)于除以 2 的 3 次方)。