1.JRE和JVM的區(qū)別
- JRE(Java Runtime Environment,Java運(yùn)行環(huán)境)包括Java虛擬機(jī)(JVM)和Java程序所需的核心類庫(kù)等,如果想要運(yùn)行一個(gè)開(kāi)發(fā)好的Java程序,計(jì)算機(jī)只需要安裝JRE即可。
- JDK(Java Development Kit,Java開(kāi)發(fā)包)是提供給Java開(kāi)發(fā)人員使用的,其中包含了Java的開(kāi)發(fā)工具,也包括了JRE。所以安裝了JDK,就不需要單獨(dú)安裝JRE了。其中的開(kāi)發(fā)工具包括:編譯工具(javac.exe),打包工具(jar.exe)等
簡(jiǎn)而言之:使用JDK開(kāi)發(fā)完成java程序,交給JRE去運(yùn)行
2.第一個(gè)java程序,HelloWorld.java
class HelloWorld{
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
1.文件名最好必須要與類名相同
2.java的入口是執(zhí)行main函數(shù)
執(zhí)行
javac HelloWorld.java # 編譯,生成class字節(jié)碼文件
java HelloWorld # 執(zhí)行class文件
3.數(shù)據(jù)類型
- 基本數(shù)據(jù)類型
數(shù)值型:byte(1),short(2),int(4),long(8),float(4),double(8)
字符型:char(2)
布爾型:boolean - 引用數(shù)據(jù)類型
類class
接口interface
數(shù)組[]
整數(shù)默認(rèn):int,小數(shù)默認(rèn):double
long i = 10000000000 // 10000000000默認(rèn)是int,所以不能賦給long
long i = 10000000000L
float j = 12.345 //12.245默認(rèn)是double,賦值給float會(huì)損失精度
float j = 12.345F
4.變量作用域
- 變量定義在哪個(gè)大括號(hào)內(nèi),它就在這個(gè)大括號(hào)內(nèi)有效
- 在同一個(gè)大括號(hào)內(nèi)不能同時(shí)定義同名的變量
類型轉(zhuǎn)換
- 隱式轉(zhuǎn)換
byte a = 10
int b = 20
int c = a+b // a會(huì)提升為int類型
- 強(qiáng)制轉(zhuǎn)換
byte i = 10000; //錯(cuò)誤,損失精度
byte i = (byte)(10000); //強(qiáng)制轉(zhuǎn)換
System.out.println(i); // 16
注意:
float f1 = (float)12.245 //f1其實(shí)是通過(guò)一個(gè)double類型轉(zhuǎn)換過(guò)來(lái)的
float f1 = 12.245F // f2本身就是一個(gè)float
- 在定義Long或者Float類型變量的時(shí)候,要加L或者F
整數(shù)默認(rèn)是int類型,浮點(diǎn)數(shù)默認(rèn)是double
byte,short在定義的時(shí)候,他們接收的其實(shí)是int類型的值,這個(gè)是自己做了一個(gè)數(shù)據(jù)檢測(cè)的,如果不再它們的范圍內(nèi),就報(bào)錯(cuò)
float和double的存儲(chǔ)結(jié)構(gòu)
易錯(cuò)知識(shí)
s+=1等價(jià)于 s = (s的數(shù)據(jù)類型)(s+1)
例如:
short s = 10
s = s + 2; // 報(bào)錯(cuò)
s+=2; // 正確
鍵盤錄入程序
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("請(qǐng)輸入數(shù)字");
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
System.out.println("你輸入的數(shù)字是"+x);
}
}
Java中的內(nèi)存分配
Java程序?yàn)榱颂岣叱绦虻男剩蛯?duì)數(shù)據(jù)進(jìn)行了不同空間的分配,具體劃分為五個(gè)內(nèi)存劃分
- 棧:存儲(chǔ)局部變量,由操作系統(tǒng)回收
- 堆:存儲(chǔ)new出來(lái)的東西,有java虛擬機(jī)回收
- 方法區(qū)
- 本地方法區(qū),和系統(tǒng)相關(guān)
- 寄存器:給CPU使用
局部變量:在方法定義中或者方法聲明上的變量
堆內(nèi)存的特點(diǎn):
A:每一個(gè)new出來(lái)的東西都有地址值
B:每個(gè)變量都有默認(rèn)值
C:使用完畢后就變成垃圾,但是并沒(méi)有立即回收。會(huì)在垃圾回收器空閑的時(shí)候回收
棧內(nèi)存的數(shù)據(jù)用完就釋放
成員變量和局部變量的區(qū)別
class Student{
int age; // 成員變量
public static void study(){
int num = 10; //局部變量
}
}
成員變量和局部變量的區(qū)別?
- 在類中的位置不同
- 成員變量:類中方法外
- 局部變量:方法內(nèi)部或者方法聲明上
- 在內(nèi)存中的位置不同
- 成員變量:堆內(nèi)存
- 局部變量:棧內(nèi)存
- 生命周期不同
- 成員變量:隨著對(duì)象的存在而存在,隨著對(duì)象的消失而消失
- 局部變量:隨著方法的調(diào)用而存在,隨著方法的調(diào)用而完畢而消失
- 初始化不同
- 成員變量有默認(rèn)的初始值
- 局部變量沒(méi)有默認(rèn)的初始值,必須先定義,賦值,才能使用
匿名對(duì)象
沒(méi)有名字的對(duì)象
new Student
匿名對(duì)象的應(yīng)用場(chǎng)景
- 調(diào)用方法,只調(diào)用一次
new Student().study(); // 調(diào)用完成之后會(huì)被回收,沒(méi)有指針指向(記住GC中的標(biāo)記清除) - 匿名對(duì)象可以作為參數(shù)傳遞
構(gòu)造方法
類的組成
1.成員變量
2.構(gòu)造方法
3.成員方法
類的初始化過(guò)程
Student s = new Student();在內(nèi)存中做了哪些事情?
- 加載Student.class文件進(jìn)內(nèi)存
- 在棧內(nèi)存為s開(kāi)辟空間
- 在堆內(nèi)存為學(xué)生對(duì)象開(kāi)辟空間
- 對(duì)學(xué)生對(duì)象的成員變量進(jìn)行默認(rèn)初始化
- 對(duì)學(xué)生對(duì)象的成員變量進(jìn)行顯示初始化
- 通過(guò)構(gòu)造方法對(duì)學(xué)生對(duì)象的成員變量賦值
- 學(xué)生對(duì)象初始化完畢,把對(duì)象地址賦給s變量
靜態(tài)成員的注意點(diǎn)(難點(diǎn))
- 所屬不同
- 靜態(tài)變量屬于類,所以也稱為類變量
- 成員變量屬于對(duì)象,所以也稱為實(shí)例變量(對(duì)象變量)
- 內(nèi)存中位置不同
- 靜態(tài)變量存儲(chǔ)于方法區(qū)的靜態(tài)區(qū)
- 成員變量存儲(chǔ)于堆內(nèi)存
- 內(nèi)存出現(xiàn)時(shí)間不同
- 靜態(tài)變量隨著類的加載而加載,隨著類的消失而消失
- 成員變量隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失
- 調(diào)用不同
- 靜態(tài)變量可以通過(guò)類名調(diào)用,也可以通過(guò)對(duì)象調(diào)用
- 成員變量只能通過(guò)對(duì)象名調(diào)用
創(chuàng)建工具類的小技巧
我們提供一個(gè)工具類,讓其他類去調(diào)用該類的方法,但是我們不希望別人去實(shí)例化對(duì)象來(lái)調(diào)用類方法,可以對(duì)構(gòu)造方法private,從而阻止類的實(shí)例化。
代碼塊
局部代碼塊,局部位置,限定變量的生命周期
public class HelloWorld {
public static void main(String[] args) {
{
int x = 3;// 局部代碼塊
}
System.out.println(x); //無(wú)法訪問(wèn)
}
}
構(gòu)造代碼塊,在類中成員位置,用{}括起來(lái)的代碼。執(zhí)行過(guò)程:每次調(diào)用構(gòu)造方法執(zhí)行前,都會(huì)執(zhí)行構(gòu)造代碼塊。作用:可以把多個(gè)構(gòu)造方法中共同代碼放到一起。
class Student{
{
System.out.println("第一個(gè)構(gòu)造代碼塊");
}
public Student(){ System.out.println("我是構(gòu)造方法"); }
{
System.out.println("第二個(gè)構(gòu)造代碼塊");
}
}
public class HelloWorld {
public static void main(String[] args) {
Student s = new Student();
}
}
輸出:
第一個(gè)構(gòu)造代碼塊
第二個(gè)構(gòu)造代碼塊
我是構(gòu)造方法
靜態(tài)代碼塊,在類中成員位置,用{}括起來(lái),用static修飾。作用:一般是對(duì)類的初始化。
class Student{
static {
System.out.println("我是靜態(tài)代碼塊");
}
{
System.out.println("我是構(gòu)造代碼塊");
}
public Student(){ System.out.println("我是構(gòu)造方法"); }
}
public class HelloWorld {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("===========");
Student s2 = new Student();
}
}
輸出:
我是靜態(tài)代碼塊
我是構(gòu)造代碼塊
我是構(gòu)造方法
===========
我是構(gòu)造代碼塊
我是構(gòu)造方法
注意:各個(gè)代碼塊的執(zhí)行順序:靜態(tài)代碼塊-》構(gòu)造代碼塊-》構(gòu)造方法;其中靜態(tài)代碼塊只執(zhí)行一次(只要一加載到內(nèi)存時(shí)就執(zhí)行),構(gòu)造代碼塊在每次創(chuàng)建對(duì)象的時(shí)候都會(huì)執(zhí)行。
class HelloWorld{
static {
System.out.println("我是靜態(tài)代碼塊");
}
{
System.out.println("我是構(gòu)造代碼塊");
}
public HelloWorld(){ System.out.println("我是構(gòu)造方法"); }
public static void main(String[] args) {
System.out.println("我是主函數(shù)");
}
}
輸出
我是靜態(tài)代碼塊
我是主函數(shù)