网站301如何做,高端品牌推广方案,wordpress付费主题破解,杭州网站建设费用多少Java代码块详解代码块概述什么是代码块#xff1f;代码块的分类局部代码块语法格式执行时机变量的作用域规则⭐静态代码块⭐语法格式执行时机⭐注意事项主要用途实例代码块#xff08;构造代码块#xff09;语法格式执行时机主要用途实例代码块与构造方法的执行顺序⭐同步代…Java代码块详解代码块概述什么是代码块代码块的分类局部代码块语法格式执行时机变量的作用域规则⭐静态代码块⭐语法格式执行时机⭐注意事项主要用途实例代码块构造代码块语法格式执行时机主要用途实例代码块与构造方法的执行顺序⭐同步代码块语法格式执行机制锁对象的选择同步代码块的优点各种代码块的执行顺序⭐例1继承关系局部代码块静态代码块实例代码块同步代码块例2静态代码块和静态变量的顺序常见问题Q1静态代码块中抛出异常会怎样Q2实例代码块和构造方法谁先执行Q3同步代码块使用不当导致死锁代码块概述什么是代码块代码块Block是指使用一对花括号{}括起来的一段代码区域。在Java中代码块可以出现在类中、方法中甚至可以独立存在。根据声明位置和修饰符的不同代码块可以分为多种类型每种类型都有其特定的执行时机和用途。代码块的分类Java中的代码块主要分为以下四大类局部代码块- 定义在方法内部的普通代码块实例代码块- 没有static修饰的代码块又称构造代码块同步代码块- 使用synchronized修饰的代码块静态代码块- 使用static修饰的代码块局部代码块局部代码块是定义在方法内部的普通代码块它是最简单的一种代码块。语法格式publicvoidmyMethod(){// 方法中的其他代码{// 局部代码块的内容System.out.println(这是局部代码块);intlocalVar100;}// 这里无法访问 localVar//System.out.println(localVar);}执行时机局部代码块的执行时机相对简单方法调用时执行当程序执行到代码块位置时执行顺序执行按照代码的书写顺序执行可多次执行如果方法被多次调用代码块也会多次执行变量的作用域规则⭐在局部代码块中变量的作用域遵循以下规则变量类型作用域范围说明代码块内定义的变量仅在代码块内有效出代码块后无法访问方法参数整个方法内有效可在代码块中访问外部方法变量整个方法内有效可在代码块中访问静态代码块⭐静态代码块是在类中使用static关键字修饰的代码块它是Java中最先执行的代码块之一。语法格式publicclassMyClass{static{// 静态代码块的内容System.out.println(这是静态代码块);}}执行时机⭐静态初始化块是用static关键字修饰的代码块用于执行类的初始化操作。其特点如下类加载时执行当JVM第一次加载类时执行只执行一次在整个程序生命周期中仅执行一次优先于main方法在main方法执行之前执行顺序执行如果有多个静态代码块按定义顺序执行具体原理双亲委派模型注意事项静态代码块中不能直接访问非静态成员静态代码块中不能使用this和super关键字静态代码块中不能抛出受检异常如果类中包含多个静态代码块它们会按顺序执行主要用途静态代码块常用于以下场景初始化静态变量为静态成员变量赋初始值加载配置文件读取properties或XML配置文件建立数据库连接创建数据库连接池注册驱动如JDBC驱动注册publicclassDatabaseConfig{privatestaticStringurl;privatestaticStringusername;privatestaticStringpassword;// 静态代码块 - 加载配置文件static{System.out.println(静态代码块开始执行加载配置文件);// 模拟读取配置文件urljdbc:mysql://localhost:3306/mydb;usernameroot;password123456;try{// 注册JDBC驱动Class.forName(com.mysql.jdbc.Driver);System.out.println(数据库驱动注册成功);}catch(ClassNotFoundExceptione){System.out.println(数据库驱动注册失败);}System.out.println(静态代码块执行完成);}publicstaticvoidmain(String[]args){System.out.println(main方法开始执行);System.out.println(数据库URL: url);System.out.println(用户名: username);}}执行结果静态代码块开始执行加载配置文件 数据库驱动注册成功 静态代码块执行完成 main方法开始执行 数据库URL: jdbc:mysql://localhost:3306/mydb 用户名: root实例代码块构造代码块实例代码块是定义在类中但没有static修饰的代码块它属于对象的级别。由于它在构造方法之前执行因此也被称为构造代码块。语法格式publicclassMyClass{{// 实例代码块的内容System.out.println(这是实例代码块);}}执行时机实例代码块的执行具有以下特点创建对象时执行每次使用new关键字创建对象时都会执行优先于构造方法在构造方法之前执行每次创建都执行无论使用哪个构造方法实例代码块都会执行顺序执行如果有多个实例代码块按定义顺序执行主要用途实例代码块主要用于以下场景提取共性代码将多个构造方法中相同的代码提取出来初始化实例变量为实例变量赋初始值执行对象创建的准备工作如日志记录、计数统计等publicclassStudent{privateStringname;privateintage;privatestaticintcount0;// 静态变量记录创建的对象数量// 实例代码块{count;// 每创建一个对象计数器加1System.out.println(实例代码块执行这是创建的第count个学生对象);}// 无参构造方法publicStudent(){System.out.println(无参构造方法执行);this.name未知;this.age0;}// 有参构造方法publicStudent(Stringname,intage){System.out.println(有参构造方法执行);this.namename;this.ageage;}publicstaticvoidmain(String[]args){System.out.println(开始创建对象...);Studentstu1newStudent();Studentstu2newStudent(张三,20);Studentstu3newStudent(李四,22);}}执行结果开始创建对象... 实例代码块执行这是创建的第1个学生对象 无参构造方法执行 实例代码块执行这是创建的第2个学生对象 有参构造方法执行 实例代码块执行这是创建的第3个学生对象 有参构造方法执行实例代码块与构造方法的执行顺序⭐通过反编译可以得知实例代码块的代码实际上会被Java编译器复制到每一个构造方法的最前面在super()调用之后。因此执行顺序是父类实例代码块 → 父类构造方法 → 子类实例代码块 → 子类构造方法同步代码块同步代码块是使用synchronized关键字修饰的代码块用于解决多线程并发访问共享资源时的线程安全问题。语法格式publicclassMyClass{publicvoidmyMethod(){synchronized(lockObject){// 需要同步的代码System.out.println(这是同步代码块);}}}执行机制同步代码块的核心机制是锁获取锁线程进入同步代码块前必须获取指定对象的锁执行代码只有获得锁的线程才能执行代码块中的内容释放锁代码块执行完毕后自动释放锁互斥访问同一时刻只有一个线程可以执行该代码块锁对象的选择同步代码块的锁对象可以是任何Java对象常见的选择有锁对象类型示例适用场景当前对象synchronized(this)实例方法中的同步类对象synchronized(MyClass.class)静态方法中的同步自定义对象private final Object lock new Object()细粒度控制字符串常量synchronized(lock)不建议使用容易造成死锁publicclassBankAccount{privatedoublebalance;// 账户余额privatefinalObjectlocknewObject();// 自定义锁对象publicBankAccount(doubleinitialBalance){this.balanceinitialBalance;}// 存款方法publicvoiddeposit(doubleamount){synchronized(lock){System.out.println(Thread.currentThread().getName() 开始存款: amount);doublenewBalancebalanceamount;// 模拟处理耗时try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}balancenewBalance;System.out.println(Thread.currentThread().getName() 存款完成当前余额: balance);}}// 取款方法publicvoidwithdraw(doubleamount){synchronized(lock){System.out.println(Thread.currentThread().getName() 开始取款: amount);if(balanceamount){doublenewBalancebalance-amount;// 模拟处理耗时try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}balancenewBalance;System.out.println(Thread.currentThread().getName() 取款成功当前余额: balance);}else{System.out.println(Thread.currentThread().getName() 取款失败余额不足);}}}publicstaticvoidmain(String[]args){BankAccountaccountnewBankAccount(1000);// 创建多个线程同时操作同一个账户Threadt1newThread(()-account.withdraw(800),张三);Threadt2newThread(()-account.deposit(500),李四);Threadt3newThread(()-account.withdraw(700),王五);t1.start();t2.start();t3.start();}}同步代码块的优点相比于同步方法同步代码块具有以下优势细粒度控制可以只同步需要同步的代码提高并发性能灵活选择锁可以使用任意对象作为锁实现更复杂的同步逻辑减少锁持有时间只对关键代码加锁减少线程阻塞时间各种代码块的执行顺序⭐例1继承关系局部代码块静态代码块实例代码块同步代码块classParent{static{System.out.println(1. 父类静态代码块);}{System.out.println(3. 父类实例代码块);}publicParent(){System.out.println(4. 父类构造方法);}}publicclassChildextendsParent{static{System.out.println(2. 子类静态代码块);}{System.out.println(5. 子类实例代码块);}publicChild(){System.out.println(6. 子类构造方法);}publicvoidtestMethod(){System.out.println(8. 开始执行testMethod方法);// 局部代码块{System.out.println(9. 局部代码块);}// 同步代码块synchronized(this){System.out.println(10. 同步代码块);}System.out.println(11. testMethod方法执行结束);}publicstaticvoidmain(String[]args){System.out.println(开始创建第一个对象);Childchild1newChild();System.out.println(\n开始调用方法);child1.testMethod();System.out.println(\n开始创建第二个对象);Childchild2newChild();}}执行结果1. 父类静态代码块 2. 子类静态代码块 开始创建第一个对象 3. 父类实例代码块 4. 父类构造方法 5. 子类实例代码块 6. 子类构造方法 开始调用方法 8. 开始执行testMethod方法 9. 局部代码块 10. 同步代码块 11. testMethod方法执行结束 开始创建第二个对象 3. 父类实例代码块 4. 父类构造方法 5. 子类实例代码块 6. 子类构造方法通过上面的示例可以总结出Java中各类代码块的完整执行顺序类加载阶段父类静态代码块 → 子类静态代码块只执行一次具体原理双亲委派模型对象创建阶段父类实例代码块 → 父类构造方法 → 子类实例代码块 → 子类构造方法方法调用阶段方法中的普通代码 → 局部代码块 → 同步代码块如果遇到例2静态代码块和静态变量的顺序publicclassOrderTrick{staticintx10;static{System.out.println(静态代码块1: x x);x20;}staticintyx5;// y会是多少static{System.out.println(静态代码块2: x x, y y);x30;y100;}publicstaticvoidmain(String[]args){System.out.println(main: x x, y y);}}静态代码块1: x 10 静态代码块2: x 20, y 25 main: x 30, y 100静态变量声明时的赋值和静态代码块按照出现顺序合并后面的赋值会覆盖前面的值常见问题Q1静态代码块中抛出异常会怎样publicclassExceptionDemo{static{// 静态代码块中抛出异常会导致类初始化失败if(true){thrownewRuntimeException(静态代码块异常);}}publicstaticvoidmain(String[]args){try{// 访问该类的任何内容都会导致ExceptionInInitializerErrorClass.forName(ExceptionDemo);}catch(ClassNotFoundExceptione){e.printStackTrace();}catch(ExceptionInInitializerErrore){System.out.println(类初始化失败: e.getCause());}}}解决方案静态代码块中应该避免抛出受检异常使用try-catch处理可能的异常。Q2实例代码块和构造方法谁先执行publicclassOrderDemo{{System.out.println(实例代码块);}publicOrderDemo(){System.out.println(构造方法);}publicstaticvoidmain(String[]args){newOrderDemo();// 输出实例代码块 → 构造方法}}答案实例代码块总是先于构造方法执行。Q3同步代码块使用不当导致死锁publicclassDeadLockDemo{privatefinalObjectlock1newObject();privatefinalObjectlock2newObject();publicvoidmethod1(){synchronized(lock1){System.out.println(method1持有lock1);try{Thread.sleep(100);}catch(InterruptedExceptione){}synchronized(lock2){System.out.println(method1持有lock2);}}}publicvoidmethod2(){synchronized(lock2){System.out.println(method2持有lock2);try{Thread.sleep(100);}catch(InterruptedExceptione){}synchronized(lock1){// 与method1相反的顺序导致死锁System.out.println(method2持有lock1);}}}}解决方案始终保持一致的锁获取顺序或使用tryLock()等高级并发工具。