Java学习 --- 代码块

目录

一、代码块

二、注意事项


一、代码块

代码块(初始化块),属于类中的成员【是类的一部分】,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。

但是和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象的隐式调用。

基本语法:

修饰符 {

 代码

};

说明:①、修饰符可选,要写只能写static。②、代码块分两类,使用static修饰的叫静态代码块,没有static修饰的叫普通代码块/非静态代码块。③、逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)。④、;号可以写,也可以省略。

代码块的优点:①、相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作。

②、场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性。

public class CodeBlock {
    public static void main(String[] args) {
        Movie movie = new Movie("西游记");
    }
}
class Movie{
    private String name;
    private double price;
    /*
      1、把相同的语句放入到一个代码块中
      2、代码块的调用顺序优于构造器。
     */
    {
        System.out.println("开始投屏");
        System.out.println("开始播放");
    }
    public Movie(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }

    public Movie(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

fb3d147d275f4e6986ed99eb68ce45d5.jpeg

二、注意事项

1、static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。

2、类在什么阶段会被加载:①、创建对象实例时(new)。②、创建子类对象实例,父类也会被加载。③、使用类的静态成员时(静态属性,静态方法)。

public class CodeBlockTest {
    public static void main(String[] args) {
        //创建对象实例时(new)
        //new AA();
        //创建子类对象实例,父类也会被加载
        //new BB();
        //使用类的静态成员时(静态属性,静态方法)
        System.out.println(CC.c);
    }
}
class AA{
    //静态代码块
    static {
        System.out.println("aa静态代码块执行");
    }
}
class BB extends AA{
    //静态代码块
    static {
        System.out.println("bb静态代码块执行");
    }
}
class CC{
    //静态属性
    public static int c = 1;
    //静态代码块
    static {
        System.out.println("cc静态代码块执行");
    }
}

3、普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会执行。

public class CodeBlockTest01 {
    public static void main(String[] args) {
        System.out.println(Dog.age);
    }
}
class Dog{
    //静态属性
    public static int age = 2;
    {
        System.out.println("普通代码块执行");
    }
}

144a47b4620745bb8895f3269806304d.jpeg

 4、创建一个对象时,在一个类调用顺序是:①、调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)。

public class CodeBlockTest02 {
    public static void main(String[] args) {
        A a = new A();
        
    }
}
class A{
    //静态属性初始化
    public static int a = getN1();
    //静态代码块
    static {
        System.out.println("A类静态代码块初始化");
    }
    //静态方法
    public static int getN1(){
        System.out.println("静态方法调用成功");
        return  100;
    }
}

②、调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)。

public class CodeBlockTest02 {
    public static void main(String[] args) {
        A a = new A();

    }
}
class A{
    //普通属性
    public int b = getN2();
    //静态属性初始化
    public static int a = getN1();
    //普通代码块
    {
        System.out.println("A类普通代码块初始化");
    }
    //静态代码块
    static {
        System.out.println("A类静态代码块初始化");
    }
    //静态方法
    public static int getN1(){
        System.out.println("静态方法调用成功");
        return  100;
    }
    //普通方法
    public int getN2(){
        System.out.println("普通方法调用成功");
        return 200;
    }
}

运行结果: 

c24442f97cb544a39819567b71058b6b.jpeg

③、调用构造器

public class CodeBlockTest02 {
    public static void main(String[] args) {
        A a = new A();

    }
}
class A{
    //普通属性
    public int b = getN2();
    //静态属性初始化
    public static int a = getN1();
    //构造器
    public A() {
        System.out.println("构造器调用成功");
    }

    //普通代码块
    {
        System.out.println("A类普通代码块初始化");
    }
    //静态代码块
    static {
        System.out.println("A类静态代码块初始化");
    }
    //静态方法
    public static int getN1(){
        System.out.println("静态方法调用成功");
        return  100;
    }
    //普通方法
    public int getN2(){
        System.out.println("普通方法调用成功");
        return 200;
    }
}

30f724c6fa064a51b1a24ef41599d502.jpeg

 5、构造器的最前面其实隐含了super()和调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于构造器和普通代码块执行的。

public class CodeBlockTest03 {
    public static void main(String[] args) {
        new B1();
    }
}
class A1{
    //普通代码块
    {
        System.out.println("A1的普通代码块初始化成功");
    }
    //构造器
    public A1() {
        //super()
        //调用普通代码块
        System.out.println("A1的构造器被调用");
    }
}
class B1 extends A1{
    //普通代码块
    {
        System.out.println("B1的普通代码块初始化成功");
    }
    //构造器
    public B1() {
        //super()
        //调用普通代码块
        System.out.println("B1的构造器被调用");
    }
}

430bb893728541bdb730ee5889b1aca4.jpeg

 6、创建一个子类时(继承关系),他们的静态代码块,静态属性初始化普通代码块,普通属性初始化,构造方法的调用顺序如下:①、父类的静态代码块和静态属性(优先级一样,按定义顺序执行)②、子类的静态代码块和静态属性(优先级一样,按定义顺序执行)③、父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)④、父类的构造方法⑤、子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)⑥、子类的构造方法。

public class CodeBlockTest04 {
    public static void main(String[] args) {
        new Test02();
    }
}
//父类
class Test01{
    //父类静态属性
    private static int a1 = getVal01();
    //父类静态代码块
    static {
        System.out.println("Test01静态代码块调用"); //第二个打印
    }
    //父类普通代码块
    {
        System.out.println("Test01普通代码块调用");//第五个打印
    }
    //父类普通属性
    public int n2 = getVal02();
    //父类静态方法
    public static int getVal01(){//第一个调用打印
        System.out.println("Test01的getVal01()方法调用");
        return 10;
    }
    //父类普通方法
    public int getVal02(){
        System.out.println("Test01的getVal02()方法调用");//第六个打印
        return 20;
    }
    //父类构造器
    public Test01() {
        System.out.println("Test01构造器调用");//第七个打印
    }
}
//子类
class Test02 extends Test01{
    //子类静态属性
    private static int b1 = getVal03();
    //子类静态代码块
    static {
        System.out.println("Test02静态代码块调用");//第四个打印
    }
    //子类普通代码块
    {
        System.out.println("Test02普通代码块调用");//第八个打印
    }
    //子类普通属性
    public int n2 = getVal04();
    //子类静态方法
    public static int getVal03(){
        System.out.println("Test02的getVal03()方法调用");//第三个打印
        return 10;
    }
    //子类普通方法
    public int getVal04(){
        System.out.println("Test02的getVal04()方法调用");//第九个打印
        return 20;
    }
    //子类构造器
    public Test02() {
        System.out.println("Test02构造器调用");//第十个打印
    }
}

0d5a6198ac0e42408362bd88a291dfda.jpeg

7、静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

public class CodeBlockTest05 {
    public static void main(String[] args) {
        new Test03();
    }
}
class Test03{
    private static int a1 = 1;
    private int a2 = 2;
    private static void A3(){
        System.out.println(3);
    }
    private void A4(){
        System.out.println(4);
    }
    //只能调用静态属性/方法
    static {
        System.out.println(a1);
        A3();
    }
    //都能调用
    {
        System.out.println(a1);
        System.out.println(a2);
        A3();
        A4();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 自定义异常可以用来在特定的业务场景中抛出异常。在判断用户名的场景中,可以自定义一个异常类来表示用户名不合法。例如: ```java class InvalidUsernameException extends Exception { public InvalidUsernameException(String message) { super(message); } } ``` 在业务逻辑中,当用户名不合法时,可以抛出该异常。例如: ```java if (!isValidUsername(username)) { throw new InvalidUsernameException("Invalid username: " + username); } ``` 在调用的地方可以使用 try-catch 语句来捕获该异常。 ```java try { register(username); } catch (InvalidUsernameException e) { System.out.println(e.getMessage()); } ``` 这样, 当用户输入不合法的用户名时,就可以在 catch 中输出错误信息了。 ### 回答2: 在Java编程中,当程序出现异常时,我们可以使用异常处理机制来处理这些异常。异常处理机制允许我们捕获、处理和报告程序执行过程中的异常情况。在Java中有很多内置的异常类型,例如:数组越界异常、空指针异常、类型转换异常等。除此之外,Java还支持自定义异常,可以根据个人需求来定义异常类型。 在本文中,我们将讨论如何使用自定义异常来判断用户名的合法性。通常情况下,我们需要根据一些规则来判断用户名是否合法,例如:是否包含非法字符、是否太短或太长等。 首先,我们需要创建一个自定义异常类,用来处理用户名不合法的情况。该异常类可以继承于Java内置的异常类,例如:Exception、RuntimeException等。在自定义异常类中,我们可以定义一些成员变量和构造方法,用来保存异常信息和创建异常对象。 然后,我们可以在判断用户名的方法中抛出自定义异常,例如: ```java public void checkUsername(String username) throws IllegalUsernameException { if (username.length() < 6 || username.length() > 18) { throw new IllegalUsernameException("用户名长度必须在6到18个字符之间!"); } if (!username.matches("^[a-zA-Z]\\w{5,17}$")) { throw new IllegalUsernameException("用户名只能包含字母、数字、下划线,且以字母开头!"); } } ``` 以上代码中,我们使用了两个条件语句来判断用户名的合法性。如果用户名不符合规则,则会抛出自定义异常对象IllegalUsernameException,并将异常信息传递给构造方法。 最后,我们需要在调用判断用户名的方法时,使用try-catch代码块来捕获异常。例如: ```java try { checkUsername(username); System.out.println("用户名合法!"); } catch (IllegalUsernameException e) { System.out.println("用户名不合法:" + e.getMessage()); } ``` 如果用户名合法,则会输出“用户名合法!”,否则会输出“用户名不合法:异常信息”。 总之,使用自定义异常可以更加灵活地处理程序中的异常情况,并能够根据个人需求来定义异常类型。在判断用户名的场景中,使用自定义异常也可以提高代码的可读性和健壮性。 ### 回答3: Java是一种很流行的编程语言,而异常处理是Java编程中必不可少的部分。Java异常处理提供了一种在程序执行期间处理错误的方法,这种错误可能导致程序的崩溃。Java中的异常分为两种:已检查异常(Checked Exception)和未检查异常(Unchecked Exception)。在开发Java应用时,有时需要自定义异常来满足特定的需求,比如在判断用户名时需要自定义一个异常。 判断用户名是Web开发和客户端开发中必不可少的部分。在Java中,可以使用正则表达式、字符过滤、长度限制等方式来验证用户名,但是当这些方式无法满足时,我们可以自定义异常来实现对用户名的验证。 首先,需要定义一个自定义异常类来处理用户名验证时可能出现的异常。我们可以创建一个继承于Exception的类,并在该类中实现构造函数,用来接收异常信息。例如: ``` public class UsernameException extends Exception { public UsernameException(String message) { super(message); } } ``` 然后,在判断用户名的方法中,如果出现了用户名不合格的情况,就可以抛出自定义异常。例如: ``` public void checkUsername(String username) throws UsernameException { if (username.length() < 6 || username.length() > 12) { throw new UsernameException("用户名长度应在6-12之间"); } if (!username.matches("[a-zA-Z0-9]+")) { throw new UsernameException("用户名只能由字母和数字组成"); } } ``` 在上述代码中,我们通过判断用户名长度和用户名是否由字母和数字组成来验证用户名,并可以通过抛出自定义异常来提示用户错误信息。 最后,在调用判断用户名方法的地方,需要使用try-catch语句来捕捉可能出现的异常。例如: ``` try { checkUsername(username); } catch (UsernameException e) { e.printStackTrace(); } ``` 通过以上方式,我们可以自定义一个异常来判断用户名,使得判断过程更方便、更灵活,也能给用户更友好的提示信息。除此之外,在其他处同样需要判断用户名时,只需要调用此方法即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸭鸭老板

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值