柚子快報邀請碼778899分享:Java 代碼塊
柚子快報邀請碼778899分享:Java 代碼塊
目錄
代碼塊是什么
普通代碼塊
構(gòu)造塊
靜態(tài)塊
同步代碼塊
代碼塊是什么
代碼塊:使用 {} 定義的一段代碼
根據(jù)代碼塊?定義的位置?和?關(guān)鍵字,代碼塊可分為以下?四種:
普通代碼塊
構(gòu)造塊
靜態(tài)塊
同步代碼塊
普通代碼塊
普通代碼塊:定義在方法中的代碼塊
public class Test {
public static void main(String[] args) {
{
int a = 5;
System.out.println("a: " + a);
}
int a = 10;
System.out.println("a: " + a);
}
}
運(yùn)行結(jié)果:
在 普通代碼塊 中定義的變量 a,不能在 方法 中使用,即 a 在代碼塊執(zhí)行完畢時就被銷毀了
普通代碼塊的執(zhí)行順序為 順序執(zhí)行(在方法中從上往下,先出現(xiàn),先執(zhí)行)?
public class Test {
public static void main(String[] args) {
int a = 10;
System.out.println("a: " + a);
{
a = 5;
System.out.println("a: " + a);
}
}
}
運(yùn)行結(jié)果:
?
在方法中定義的變量可以在代碼塊中進(jìn)行訪問和修改
構(gòu)造塊
構(gòu)造塊:定義在類中的代碼塊,也叫做實例代碼塊
構(gòu)造代碼塊一般用于初始化實例成員變量
public class Student {
private int id;
private String name;
private int age;
public Student() {
System.out.println("init...");
}
// 構(gòu)造代碼塊
{
id = 1;
name = "張三";
age = 19;
System.out.println("執(zhí)行構(gòu)造代碼塊");
}
public void info() {
System.out.println("id: " + id + " name: " + name + " age: " + age);
}
public static void main(String[] args) {
Student student = new Student();
student.info();
}
}
運(yùn)行結(jié)果:
?
構(gòu)造代碼塊在構(gòu)造方法之前執(zhí)行,且與構(gòu)造代碼塊的位置無關(guān),無論構(gòu)造代碼塊放在哪里,都會先執(zhí)行構(gòu)造代碼塊,再執(zhí)行構(gòu)造方法
public class Student {
private int id;
private String name;
private int age;
public Student() {
System.out.println("init...");
}
// 構(gòu)造代碼塊
{
id = 1;
name = "張三";
age = 19;
System.out.println("執(zhí)行構(gòu)造代碼塊");
}
{
id = 2;
System.out.println("再次執(zhí)行構(gòu)造方法");
}
public void info() {
System.out.println("id: " + id + " name: " + name + " age: " + age);
}
public static void main(String[] args) {
Student student = new Student();
student.info();
}
}
運(yùn)行結(jié)果:
?
當(dāng)有多個構(gòu)造代碼塊時,?編譯器會按照定義的先后順序,將這些構(gòu)造代碼塊進(jìn)行合并,然后按照順序執(zhí)行
使用構(gòu)造方法就可以初始化實例成員變量,為什么還需要使用構(gòu)造代碼塊呢?
構(gòu)造代碼塊相當(dāng)于是對構(gòu)造器的補(bǔ)充
還是上述例子:
public class Student {
private int id;
private String name;
private int age;
public Student() {
}
public Student(int id) {
this.id = id;
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 構(gòu)造代碼塊
{
id = 1;
name = "張三";
age = 19;
System.out.println("執(zhí)行構(gòu)造代碼塊");
}
public void info() {
System.out.println("id: " + id + " name: " + name + " age: " + age);
}
public static void main(String[] args) {
Student student = new Student();
student.info();
Student student1 = new Student(2, "李四");
student1.info();
Student student2 = new Student(3, "王五", 18);
student2.info();
}
}
運(yùn)行結(jié)果:
?
無論調(diào)用哪個構(gòu)造方法,在每次創(chuàng)建實例時,都會先執(zhí)行構(gòu)造代碼塊,再執(zhí)行構(gòu)造方法,因此,若多個構(gòu)造器中都有重復(fù)的語句,就可以將其抽取到構(gòu)造代碼塊中,或是在構(gòu)造代碼塊中為變量賦默認(rèn)值
靜態(tài)塊
靜態(tài)代碼塊:使用 static 定義的代碼塊
一般用于初始化靜態(tài)成員變量
public class Student {
private int id;
private String name;
private int age;
private static String classRoom;
public Student() {
}
public Student(int id) {
this.id = id;
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 構(gòu)造代碼塊
{
id = 1;
name = "張三";
age = 19;
System.out.println("執(zhí)行構(gòu)造代碼塊");
}
// 靜態(tài)代碼塊
static {
classRoom = "一班";
System.out.println("執(zhí)行靜態(tài)代碼塊");
}
public void info() {
System.out.println("id: " + id + " name: " + name + " age: " + age);
}
public static void main(String[] args) {
Student student = new Student();
student.info();
Student student1 = new Student(2, "李四");
student1.info();
Student student2 = new Student(3, "王五", 18);
student2.info();
}
}
運(yùn)行結(jié)果:
我們可以發(fā)現(xiàn):靜態(tài)代碼塊在構(gòu)造代碼塊之前執(zhí)行,且只執(zhí)行了一次
為什么靜態(tài)代碼塊只執(zhí)行了一次呢?
靜態(tài)代碼塊一般用于初始化靜態(tài)成員變量,而靜態(tài)成員變量是類的屬性,因此,靜態(tài)成員變量是在 JVM 進(jìn)行?類加載?時就為其開辟了空間并進(jìn)行了初始化,也就是說靜態(tài)代碼塊在類加載時就被執(zhí)行了,后續(xù)也就不會被執(zhí)行了
public class Student {
private int id;
private String name;
private int age;
private static String classRoom;
public Student() {
}
public Student(int id) {
this.id = id;
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 構(gòu)造代碼塊
{
id = 1;
name = "張三";
age = 19;
System.out.println("執(zhí)行構(gòu)造代碼塊");
}
// 靜態(tài)代碼塊
static {
classRoom = "一班";
System.out.println("執(zhí)行靜態(tài)代碼塊");
}
static {
classRoom = "二班";
System.out.println("再次執(zhí)行靜態(tài)代碼塊");
}
public void info() {
System.out.println("id: " + id + " name: " + name + " age: " + age + " class: " + classRoom);
}
public static void main(String[] args) {
Student student = new Student();
student.info();
Student student1 = new Student(2, "李四");
student1.info();
Student student2 = new Student(3, "王五", 18);
student2.info();
}
}
運(yùn)行結(jié)果:
若類中包含多個靜態(tài)代碼塊,在編譯代碼時,編譯器會按照定義的先后順序,將這些靜態(tài)代碼塊進(jìn)行合并,然后按照順序執(zhí)行
即:
靜態(tài)代碼塊無論創(chuàng)建多少個對象,都只會執(zhí)行一次(在類加載時執(zhí)行)
構(gòu)造代碼塊每次創(chuàng)建對象時都會執(zhí)行(在創(chuàng)建對象時執(zhí)行)
同步代碼塊
什么是同步?
在 Java 中,允許多個線程并發(fā)執(zhí)行,當(dāng)多個線程需要訪問和操作同一個資源(共享資源)時,多個線程之間就可能會產(chǎn)生沖突,出現(xiàn)數(shù)據(jù)不一致或破壞數(shù)據(jù)完整性的問題。此時就可以使用?同步代碼塊(synchronized block)來控制多個線程對共享資源的訪問,將代碼塊標(biāo)記為同步(也就是進(jìn)行?加鎖?操作),保證同一時間只有一個線程能夠執(zhí)行該代碼塊
在 Java 中一般使用 synchronized 來實現(xiàn)同步代碼塊
synchronized (Object locker) {
? ? ? ? ...
}
其中 locker 表示加鎖的對象,?只有獲取到該對象的鎖的線程才能繼續(xù)執(zhí)行代碼塊,這個對象可以是任意的 Java 對象
例如:
public class Test {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Object locker = new Object();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized (locker) {
count++;
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized (locker) {
count++;
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("count: " + count);
}
}
同步代碼塊涉及到很多知識,例如 如何進(jìn)行加鎖、有哪些注意事項、加鎖過程中可能會產(chǎn)生哪些問題...
更多關(guān)于同步代碼塊的知識,在這里就不展開講解了,可以參考之前的文章:
線程安全問題_線程安全的例子-CSDN博客
柚子快報邀請碼778899分享:Java 代碼塊
好文鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。