首页 > 其他分享 >静态static小问题、顺序结构、选择结构(if(单分支、双分支、多分支)、switch)、循环结构(while、do……while、for)、break、continue、label标签202412

静态static小问题、顺序结构、选择结构(if(单分支、双分支、多分支)、switch)、循环结构(while、do……while、for)、break、continue、label标签202412

时间:2024-12-24 21:08:46浏览次数:4  
标签:scanner 分支 System while 循环 println out public 结构

静态static小问题20241224

package com.pangHuHuStudyJava.scanner;
import java.util.Scanner;
public class Demo04 {
    public static void main(String[] args) {
        int i;
        float f;
        Scanner scanner = new Scanner(System.in);
        // 输入整数
        System.out.println("请输入一个整数:");
        if (scanner.hasNextInt()) {
            i = scanner.nextInt();
            System.out.println("你输入的整数是:" + i);
        } else {
            System.out.println("你输入的不是整数!");
            scanner.next(); // 清除错误输入
        }
        // 输入小数
        System.out.println("请输入一个小数:");
        if (scanner.hasNextFloat()) {
            f = scanner.nextFloat();
            System.out.println("你输入的小数是:" + f);
        } else {
            System.out.println("你输入的不是小数!");
            scanner.next(); // 清除错误输入
        }
        scanner.close(); // 关闭资源
    }
}

为什么我把i f 定义在main方法外就错了啊?

package com.pangHuHuStudyJava.scanner;
import java.util.Scanner;
public class Demo04 {
 int i;
 float f;
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     // 输入整数
     System.out.println("请输入一个整数:");
     if (scanner.hasNextInt()) {
         i = scanner.nextInt();
         System.out.println("你输入的整数是:" + i);
     } else {
         System.out.println("你输入的不是整数!");
         scanner.next(); // 清除错误输入
     }
     // 输入小数
     System.out.println("请输入一个小数:");
     if (scanner.hasNextFloat()) {
         f = scanner.nextFloat();
         System.out.println("你输入的小数是:" + f);
     } else {
         System.out.println("你输入的不是小数!");
         scanner.next(); // 清除错误输入
     }
     scanner.close(); // 关闭资源
 }
}

变量定义位置的区别

  1. 定义在方法内部
    • 变量 if 定义在 main 方法内,属于局部变量
    • 局部变量的作用范围仅限于所在方法,在方法执行结束后,变量也随之销毁。
    • 这种情况下,变量在定义时会在堆栈中分配空间,Java 会确保你在使用局部变量前对其赋值
  2. 定义在方法外部(类内)
    • 如果将变量定义在 main 方法外,且不加Static而直接放在类中它们就成为类的成员变量,也叫实例变量
    • 成员变量的作用范围是整个类它们依赖于类的实例如果没有创建实例成员变量是无法直接使用的除非是 static 修饰的类变量)。
    • 你的 if 是非 static 成员变量,而 main 方法是 static 的,不能直接访问这些非 static 成员变量。

为什么会出错?

在 Java 中,main 方法是一个静态方法 (static),属于类本身,而不是类的对象。如果 if 是非静态变量,那么它们属于类的对象,必须通过对象来访问。由于 main 是静态方法,它无法直接访问非静态变量。

那如果我的方法不是静态的可以访问实例变量吗?

是的,非静态方法可以直接访问实例变量因为非静态方法是依赖于对象实例而实例变量也属于对象,所以非静态方法能够直接访问实例变量。

示例代码

public class Example {
    int instanceVar = 42; // 实例变量
    static int staticVar = 100; // 静态变量

    // 非静态方法
    public void nonStaticMethod() {
        System.out.println("实例变量: " + instanceVar); // 可以直接访问实例变量
        System.out.println("静态变量: " + staticVar);  // 也可以直接访问静态变量
    }

    public static void main(String[] args) {
        Example obj = new Example(); // 创建实例
        obj.nonStaticMethod(); // 调用非静态方法
    }
}

输出:

makefile复制代码实例变量: 42
静态变量: 100

为什么非静态方法可以访问实例变量?

  1. 非静态方法需要实例化对象:
    • 非静态方法只能通过对象调用,而对象本身携带实例变量的值。因此,非静态方法可以直接访问实例变量。
  2. 对象的作用域:
    • 每个对象实例有独立的实例变量(存储在堆内存中),非静态方法运行时可以引用这些变量。
  3. 非静态方法可以访问静态变量:
    • 静态变量是全局共享的,所有实例都可以访问静态变量,非静态方法也可以直接访问。

总结

  • 非静态方法可以直接访问实例变量和静态变量
  • 实例变量属于对象,非静态方法可以通过对象(实例)直接引用。
  • 静态变量属于类(类变量),无论是静态方法还是非静态方法都可以访问。

如何修复?

有两种方法:

方法 1:将 if 定义为静态变量

package com.pangHuHuStudyJava.scanner;
import java.util.Scanner;
public class Demo04 {
    static int i; // 定义为静态变量
    static float f; // 定义为静态变量
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入整数
        System.out.println("请输入一个整数:");
        if (scanner.hasNextInt()) {
            i = scanner.nextInt();
            System.out.println("你输入的整数是:" + i);
        } else {
            System.out.println("你输入的不是整数!");
            scanner.next(); // 清除错误输入
        }
        // 输入小数
        System.out.println("请输入一个小数:");
        if (scanner.hasNextFloat()) {
            f = scanner.nextFloat();
            System.out.println("你输入的小数是:" + f);
        } else {
            System.out.println("你输入的不是小数!");
            scanner.next(); // 清除错误输入
        }
        scanner.close();
    }
}

方法 2:通过对象访问非静态变量

如果 if 是非静态成员变量,需要创建类的实例才能访问:

package com.pangHuHuStudyJava.scanner;

import java.util.Scanner;

public class Demo04 {
    int i; // 非静态变量
    float f; // 非静态变量

    public static void main(String[] args) {
        Demo04 demo = new Demo04(); // 创建类的实例   其实还是通过构造实例(对象)去修改实例变量
        Scanner scanner = new Scanner(System.in);
        // 输入整数
        System.out.println("请输入一个整数:");
        if (scanner.hasNextInt()) {
            demo.i = scanner.nextInt();
            System.out.println("你输入的整数是:" + demo.i);
        } else {
            System.out.println("你输入的不是整数!");
            scanner.next(); // 清除错误输入
        }

        // 输入小数
        System.out.println("请输入一个小数:");
        if (scanner.hasNextFloat()) {
            demo.f = scanner.nextFloat();
            System.out.println("你输入的小数是:" + demo.f);
        } else {
            System.out.println("你输入的不是小数!");
            scanner.next(); // 清除错误输入
        }
        scanner.close();
    }
}

总结

  • 如果你想在 main 方法直接访问变量,那么将它们定义为 static 是最方便的方式。
  • 如果变量不需要是静态的,可以通过创建对象来访问非静态成员变量。
  • 静态方法无法直接访问非静态变量,因为静态方法、变量属于类,非静态变量属于对象。

顺序结构 20241224

顺序结构

◆JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。

◆ 顺序结构是最简单的算法结构。

◆语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。

package com.pangHuHuStudyJava.struct;
public class SequentialStructure {
 public static void main(String[] args) {
     System.out.println("hello1");
     System.out.println("hello2");
     System.out.println("hello3");
     System.out.println("hello4");
 }
}

if()选择结构20241224

if单选择结构

if双选择结构

if多选择结构

嵌套的if结构

switch多选择结构

if单选择结构

我们很多时候要判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用if语句来表示

image-20241224112802044image-20241224113021167

package com.pangHuHuStudyJava.struct;
import java.util.Scanner;
/*
****************if单选择结构************
if双选择结构
if多选择结构
嵌套的if结构
switch多选择结构
*/
public class IfSelectStructureDemo01 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     String str=scanner.nextLine();
     if(str.equals("Hello")){//比较字符串内容!
         System.out.println("你输入的字符串是:Hello");
     }
     System.out.println("End");
     scanner.close();
 }
}

if()else双选择结构

  • 语法:

    if(布尔表达式){

    //如果布尔表达式的值为true

    }else{

    //如果布尔表达式的值为false

    }
    img

    package com.pangHuHuStudyJava.struct;
    import java.util.Scanner;
    /*
    if单选择结构
    ****************if双选择结构****************
    if多选择结构
    嵌套的if结构
    switch多选择结构
     */
    public class IfSelectStructureDemo02 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入你的分数:");
            int score=scanner.nextInt();
            if(score>=60){
                System.out.println("恭喜你,你的成绩及格了!");
            }
            else{
                System.out.println("很遗憾,你的成绩不及格!");
            }
            scanner.close();
        }
    }
    

if多选择结构

  • 我们发现刚才的代码不符合实际情况,真是的情况还可能存在ABCD,存在区间多级判断。比如90-100就是A,80-90就是B..等等,在生活中我们很多时候的选择也不仅仅只有俩个,所以我们需要一个多选择结构来处理这类问题!

  • 语法:

    if(布尔表达式1){
        //如果布尔表达式1的值为true执行代码
    }else if(布尔表达式2){
        //如果布尔表达式2的值为true执行代码
    }else if(布尔表达式3){
        //如果布尔表达式3的值为true执行代码
    }else {
        //如果以上布尔表达式都不为true执行代码
    

    img

    package com.pangHuHuStudyJava.struct;
    import java.util.Scanner;
    /*
    if单选择结构
    if双选择结构
    ****************if多选择结构****************
    嵌套的if结构
    switch多选择结构
     */
    public class IfSelectStructureDemo03 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入你的成绩");
            int score = scanner.nextInt();
            if(score==100){
                System.out.println("恭喜!你的成绩是满分!");
            }
            else if(score>=90  && score<100){
                System.out.println("你的成绩为A等!");
            }
            else if(score>=80  && score<90){
                System.out.println("你的成绩为B等!");
            }
            else if(score>=80 && score<70){
                System.out.println("你的成绩为C等!");
            }
            else if(score>=60  && score<70){
                System.out.println("你的成绩为D等!");
            }
            else if(score>=0 && score<60){
                System.out.println("你的成绩不合格!");
            }
            else {
                System.out.println("你输入的成绩不合法!");
            }
    
            scanner.close();
        }
    }
    

嵌套的if结构

  • 使用嵌套的if...else语句是合法的。也就是说你可以在另一个if或者else if语句中使用if或者else if语句。你可以像if语句一样嵌套else if...else。

  • 语法:

    if(布尔表达式1){
        ////如果布尔表达式1的值为true执行代码
    }if(布尔表达式2){
        ////如果布尔表达式2的值为true执行代码
    }
    

switch选择结构

  • 多选择结构还有一个实现方式是:switch case语句

  • switch case语句判断一个变量与一系列值中每个值是否相等,每个值称为一个分支

  • switch语句中的变量类型可以是:

    • byte、short、int、char

    • 从Java SE 7 开始,switch 支持字符串String类型了

    • 同时case标签必须为字符串常量或字面量

switch(expression){
    case value :
        //语句块
        break;
    case value :
        //语句块
        break;
    default :
        //语句块
}
  • switch语句中,case具有穿透现象!

    1. 执行case分支语句时,即使case 满足条件如果没加 break;,继续也会继续向下执行,直到整个switch语句执行完毕才能结束。

    2. 当语句块后有== break==;时,程序会跳出switch语句。

  • default关键字在 switch 语句不匹配 case 中所有值时执行。

package com.pangHuHuStudyJava.struct;
/*
if单选择结构
if双选择结构
if多选择结构
嵌套的if结构
****************switch多选择结构****************
*/
import java.util.Scanner;
public class SwitchSelectStructureDemo01 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     String str = scanner.nextLine();
     switch (str) {
         case "巢安龙":
             System.out.println("你输入的是:巢安龙");
             break;
         case "CAL":
             System.out.println("你输入的是:CAL");
             break;
         default:
             System.out.println("抱歉,没有识别到你输入的字符!");
             break;
     }
     scanner.close();
 }
}

哈希值问题 反编译 javap -c ****.class

package com.pangHuHuStudyJava.struct;
/*
if单选择结构
if双选择结构
if多选择结构
嵌套的if结构
****************switch多选择结构****************
*/
import java.util.Scanner;
public class SwitchSelectStructureDemo01 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     String str = scanner.nextLine();
     switch (str) {
         case "巢安龙":
             System.out.println("你输入的是:巢安龙");
             break;
         case "CAL":
             System.out.println("你输入的是:CAL");
             break;
         default:
             System.out.println("抱歉,没有识别到你输入的字符!");
             break;
     }
     System.out.println("巢安龙".hashCode());  // 输出 23863954
     System.out.println("CAL".hashCode());   // 输出 66478
     System.out.println(str.hashCode());   // 输出 66478
     scanner.close();
 }
}

第25行 第26行 打印两字符串的哈希值

第27行 打印输入字符串的哈希值!

输入:asdasdasda
抱歉,没有识别到你输入的字符!
23863954
66478
-1817180433

D:\download\code\JavaSE\out\production\基础语法\com\pangHuHuStudyJava\struct>dir
 驱动器 D 中的卷是 新加卷
 卷的序列号是 5073-C048

 D:\download\code\JavaSE\out\production\基础语法\com\pangHuHuStudyJava\struct 的目录

2024/12/24  15:40    <DIR>          .
2024/12/24  15:05    <DIR>          ..
2024/12/24  15:05             1,072 IfSelectStructureDemo01.class
2024/12/24  15:09             1,038 IfSelectStructureDemo02.class
2024/12/24  15:37             1,326 IfSelectStructureDemo03.class
2024/12/24  15:05               685 SequentialStructure.class
2024/12/24  15:37             1,302 SwitchSelectStructureDemo01.class
               5 个文件          5,423 字节
               2 个目录 183,152,959,488 可用字节

D:\download\code\JavaSE\out\production\基础语法\com\pangHuHuStudyJava\struct>javap -c SwitchSelectStructureDemo01.class
Compiled from "SwitchSelectStructureDemo01.java"
public class com.pangHuHuStudyJava.struct.SwitchSelectStructureDemo01 {
  public com.pangHuHuStudyJava.struct.SwitchSelectStructureDemo01();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/Scanner
       3: dup
       4: getstatic     #3                  // Field java/lang/System.in:Ljava/io/InputStream;
       7: invokespecial #4                  // Method java/util/Scanner."<init>":(Ljava/io/InputStream;)V
      10: astore_1
      11: aload_1
      12: invokevirtual #5                  // Method java/util/Scanner.nextLine:()Ljava/lang/String;
      15: astore_2
      16: aload_2
      17: astore_3
      18: iconst_m1
      19: istore        4
      21: aload_3
      22: invokevirtual #6                  // Method java/lang/String.hashCode:()I
      25: lookupswitch  { // 2
                 66478: 67
              23863954: 52
               default: 79
          }
      52: aload_3
      53: ldc           #7                  // String 巢安龙
      55: invokevirtual #8                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      58: ifeq          79
      61: iconst_0
      62: istore        4
      64: goto          79
      67: aload_3
      68: ldc           #9                  // String CAL
      70: invokevirtual #8                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      73: ifeq          79
      76: iconst_1
      77: istore        4
      79: iload         4
      81: lookupswitch  { // 2
                     0: 108
                     1: 116
               default: 124
          }
     108: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
     111: ldc           #11                 // String 你输入的是:巢安龙
     113: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     116: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
     119: ldc           #13                 // String 你输入的是:CAL
     121: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     124: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
     127: ldc           #14                 // String 抱歉,没有识别到你输入的字符!
     129: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     132: aload_1
     133: invokevirtual #15                 // Method java/util/Scanner.close:()V
     136: return
}

D:\download\code\JavaSE\out\production\基础语法\com\pangHuHuStudyJava\struct>

第17行用了javap 反编译命令 javap -c SwitchSelectStructureDemo01.class

第43 44 行显示了哈希值

循环结构20241224

while循环结构

  • while是最基本的循环,其结构式为:
while (布尔表达式){

}
  • 只要布尔表达式为true,循环就会一直执行下去
  • 我们大多数情况是会让循环停下来的,我们需要一个让表达式失效的方式来结束循环
  • 少数情况需要循环一直执行,比如服务器的请求相应监听等
  • 循环条件一直为true就会造成无限循环【死循环】,我们正常的业务应该尽量避免死循环。会影响程序性能或者程序卡死崩溃。
package com.pangHuHuStudyJava.struct;
/**
 * while循环
 */
public class CyclicStructureDemo01_While {
    public static void main(String[] args) {
        int i=0;
        int sum=0;
        /*while(i<100){
            i++;
            System.out.println(i);*/  //循环输出1~100
        while(i<100){
            //i++;
            //sum+=i;
            sum+=++i;
        }
        System.out.println(sum);
    }
}

输出结果:5050

do ...while循环

  • 对于while语句而言,如果不满足条件,就不能进入循环。但有时候,我们需要即使不满足条件,也至少执行一次

  • do ... while循环和 while循环相似,不同的是,do ...while循环至少会执行一次

    do{
        //代码语句
    }while(布尔表达式);
    
public class CyclicStructureDemo01_DoWhile {
    public static void main(String[] args) {
        int i = 0;
        int sum=0;
        do {
            i++;
            sum+=i;
        }while(i<100);
        System.out.println(sum);
    }
}

输出:5050

  • while 和 do ...while 的区别:

    • while先判断后执行,do ...while是先执行后判断!
    • do ...while总是保证循环体会被至少执行一次。这是他们的主要差别。
package com.pangHuHuStudyJava.struct;
import java.sql.SQLOutput;
//简单说明一下 while 和do while 之间的区别
//do while 会至少执行一次先执行再判断
//while 是先判断再执行
public class CyclicStructureDemo03_DoWhile {
    public static void main(String[] args) {
        int a=0;
        while (a<0){
            a++;
        }
        System.out.println(a);
        System.out.println("==================");
        do{
            a++;
        }while (a<0);
        System.out.println(a);
    }
}

输出结果:

0

================

1

for循环

  • for循环语句是支持迭代的一种通用结构是最有效、最灵活的循环结构

  • for循环执行的次数是在执行前就确定的。语法格式如下:

    for(初始化值;布尔表达式;更新){
        //代码语句
    }
    
  • 关于for循环有以下几点说明:

    最先执行初始化步骤可以说明一种类型,但可初始化一个或多个循环控制变量也可以是空语句。
    然后,检测布尔表达式的值如果为true,循环体被执行如果为false,循环中止,开始执行循环体后面的语句
    再次检测布尔表达式,循环执行上面的过程
    for(;;)//死循环
    {
        //语句块__________________注意这也是个死循环
    }
    
package com.pangHuHuStudyJava.struct;
public class CyclicStructureDemo04_For {
 public static void main(String[] args) {
     int a = 1;
     for (;;)
     {
         System.out.println(a);
         a++;
     }
 }
}

等同于

package com.pangHuHuStudyJava.struct;
public class CyclicStructureDemo04_For {
 public static void main(String[] args) {
     int a = 1;
     while(true){
         System.out.println(a);
         a++;
     }
 }
}

IDEA 快捷键 100.for

1.计算1~100内的所有奇数和 偶数和
package com.pangHuHuStudyJava.struct;
//计算1~100内奇数和、偶数和
public class CyclicStructureDemo05_For {
 public static void main(String[] args) {
     int odd_sum = 0;
     int even_sum = 0;
     for (int i = 0; i <=100; i++) {
         if(i % 2 == 0) {
             odd_sum += i;
         }
         if(i % 2 ==1) {
             even_sum += i;
         }
     }
     System.out.println("odd_sum:"+odd_sum);
     System.out.println("even_sum:"+even_sum);
 }
}

输出结果:

odd_sum:2550
even_sum:2500

2.用while 或者for循环输出1-1000之间能被5整除的数,且每行输出3个
package com.pangHuHuStudyJava.struct;
//用while 或者for循环输出1-1000之间能被5整除的数,且每行输出3个
public class CyclicStructureDemo06_For {
 public static void main(String[] args) {
     int count=0;
     for (int i = 0; i < 1000; i++) {
         if(i % 5 ==0 ){
             System.out.print(i+"\t");
             count++;
             if (count % 3 ==0){
                 System.out.println("\n");
             }
         }
     }
 }
}
public static void main(String[] args) {
     int count = 0;
     int i=0;
     while(i<=1000){
         if(i % 5 ==0){
             System.out.print(i+"\t");
             count++;
             if(count % 3==0){
                 System.out.println();
             }
         }
         i++;
     }
 }
输出
System.out.print(i+"\t");//输出不换行
System.out.println();//输出换行
3.打印99乘法表
package com.pangHuHuStudyJava.struct;
//打印99乘法表
public class CyclicStructureDemo07_For {
 public static void main(String[] args) {
     for (int i = 1; i < 10; i++) {
         for (int j = 1; j <= i; j++) {
             System.out.print(j+"*"+i+"="+(i*j)+"\t");
         }
         System.out.println();
     }
 }
}
1*1=1	
1*2=2	2*2=4	
1*3=3	2*3=6	3*3=9	
1*4=4	2*4=8	3*4=12	4*4=16	
1*5=5	2*5=10	3*5=15	4*5=20	5*5=25	
1*6=6	2*6=12	3*6=18	4*6=24	5*6=30	6*6=36	
1*7=7	2*7=14	3*7=21	4*7=28	5*7=35	6*7=42	7*7=49	
1*8=8	2*8=16	3*8=24	4*8=32	5*8=40	6*8=48	7*8=56	8*8=64	
1*9=9	2*9=18	3*9=27	4*9=36	5*9=45	6*9=54	7*9=63	8*9=72	9*9=81	
4.增强型for循环
  • 这里我们先只是见一面,做个了解,之后数组我们重点使用
  • Java5引入了一种主要用于数组或集合的增强型for循环。
  • Java增强for循环语法格式如下:
for (int x :numbers){
         System.out.println(x);
     }
package com.pangHuHuStudyJava.struct;
//增强型 for循环
public class CyclicStructureDemo08_For {
    public static void main(String[] args) {
        int[] numbers ={10,15,20,25,30,35};
        for (int i = 0; i < numbers.length; i++) {
            System.out.println(numbers[i]);
        }
        System.out.println("=================");
        for (int x :numbers){
            System.out.println(x);
        }
    }
}

Break continue label 标签 20241224

break、continue、goto

break

break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

public static void main(String[] args) {
 int i=0;
 while (i<100){
     i++;
     System.out.println(i);
     if (i==30){
         break;
     }
 }
 System.out.println("break停止循环");//break是跳出了循环并没有中止程序。
package com.pangHuHuStudyJava.struct;
//测试break  跳循环的范围  跳出最近一层
public class BreakDemo02 {
 public static void main(String[] args) {
     for (int i = 1; i < 3; i++) { //外部循环
         for (int j = 1; j < 10; j++) { //内部循环
             if(j % 3 == 0){
                 System.out.println("马上执行到第9行break,内部循环中断");
                 break;//注意这里退出最近循环 内部的的for循环退出  第11行不执行的
             }
             System.out.println("i=" + i + " j=" + j);//这行,到break执行后是不执行的,程序直接跳到13行  执行外部循环
         }
         System.out.println("外部循环继续");
     }
 }
}

输出结果

i=1 j=1
i=1 j=2
马上执行到第9行break,内部循环中断
外部循环继续
i=2 j=1
i=2 j=2
马上执行到第9行break,内部循环中断
外部循环继续

break 如何跳出两层循环呢?

方法一:使用布尔值 在第一次跳出 设置布尔值变化,外一层循环判断布尔值变化,若变化,则再break一次退出外层循环

package com.pangHuHuStudyJava.struct;
public class BreakDemo03 {
 public static void main(String[] args) {
     boolean flag = true;
     for (int i = 1; i < 3; i++) {
         for (int j = 1; j < 10; j++) {
             if(j % 3 == 0){
                 flag = false;  //在第一次跳出前,改变标志位
                 System.out.println("跳出内层循环");
                 break;//执行到此处时,立即退出最近循环(内层for循环) 跳到15行去了
             }
             System.out.println("i="+i+",j="+j);
         }
         if(flag==false){   //检测到标志位变化 执行16行
             System.out.println("跳出外层循环");
             break;//退出最外层循环  (外层for 循环)
         }
     }
 }
}

输出结果:

i=1,j=1
i=1,j=2
跳出内层循环
跳出外层循环

方法二:设置标签,break 直接跳转到标签位置

package com.pangHuHuStudyJava.struct;
public class BreakDemo04 {
    public static void main(String[] args) {
        outer:for (int i = 1; i < 4; i++) {
                for (int j = 1; j < 10; j++) {
                    if(j % 3 == 0){
                        System.out.println("开始跳转,直接退出最外层循环");
                        break outer;//直接跳到outer位置,设置在最外层循环  跳出整个外层循环,程序从跳到14行了
                    }
                    System.out.println("i="+i+",j="+j);//第六句判断成立后执行到第8句 这一句是不执行的 直接跳到14行
                }
                System.out.println("test");//第六句判断成立后执行到第8句 这一句是不执行的 直接跳到14行
            }
        System.out.println("test1");
        }
}

输出结果:

i=1,j=1
i=1,j=2
开始跳转,直接退出最外层循环
test1

continue

continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着执行下一次是否执行循环的判定。

package com.pangHuHuStudyJava.struct;
//测试continue
public class ContinueDemo01 {
    public static void main(String[] args) {
        int num=0;
        while(num<100){
            num++;
            if(num % 30 ==0){
                System.out.println();//每次跳出前 换下行
                continue;//直接跳出  此次循环 (num=30) 但是循环还是会继续的程序又从第6行开始(31 61 91)  相当于只剔除了 30 60 90
            }
            System.out.print(num+"\t");
        }
    }
}

输出结果:

1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29	
31	32	33	34	35	36	37	38	39	40	41	42	43	44	45	46	47	48	49	50	51	52	53	54	55	56	57	58	59	
61	62	63	64	65	66	67	68	69	70	71	72	73	74	75	76	77	78	79	80	81	82	83	84	85	86	87	88	89	
91	92	93	94	95	96	97	98	99	100	

如果是双层循环,可以用continue跳标签 比较下和break break 跳标签的区别

package com.pangHuHuStudyJava.struct;
public class ContinueDemo02 {
 public static void main(String[] args) {
     for (int i = 1; i < 4; i++) {
         for (int j = 1; j < 10; j++) {
             if (j % 3 == 0) {
                 System.out.println("开始跳转");
                 break;//直接跳出当前循环 程序从12行开始 执行到外层循环底部在看是否满足循环条件,继续两组循环
             }
             System.out.println("i=" + i + ",j=" + j);
         }
         System.out.println("test");
     }
     System.out.println("test1");
 }
}

输出结果:

i=1,j=1
i=1,j=2
开始跳转
test
i=2,j=1
i=2,j=2
开始跳转
test
i=3,j=1
i=3,j=2
开始跳转
test
test1

continue 跳转标签

package com.pangHuHuStudyJava.struct;
public class ContinueDemo03 {
    public static void main(String[] args) {
        outer:for (int i = 1; i < 4; i++) {
            for (int j = 1; j < 10; j++) {
                if(j % 3 == 0){
                    System.out.println("开始跳转");
                    continue outer;//跳出此次循环,到第四行判断程序程序是否继续循环  第12行跳开了
                }
                System.out.println("i="+i+",j="+j);
            }
            System.out.println("test");
        }
        System.out.println("test1");
    }
}

输出结果:

i=1,j=1
i=1,j=2
开始跳转
i=2,j=1
i=2,j=2
开始跳转
i=3,j=1
i=3,j=2
开始跳转
test1

goto

goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用,Java没有goto。然而在break和continue两个关键字身上,我们仍能看出一些goto的影子---带标签的break和continue

“标签”是指后面跟一个冒号的标识符,例如label:

对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

总结:

我这是用了label 方法对吧?相当于goto方法,这种方法有什么好处,有什么坏处,一般在什么场合用它,有什么经典案例可以参考

ChatGPT 说:

ChatGPT

是的,你的代码使用了 Java 的 label(标签)方法,与传统的 goto 方式有一定相似性,但 Java 中没有直接的 goto 关键字。标签结合 breakcontinue 可以实现类似 goto 的跳转逻辑。以下是对这种方法的优缺点分析、适用场景以及经典案例。


标签方法的优缺点

优点

  1. 控制复杂循环流程
    • 当嵌套循环层级较深时,标签方法可以快速跳出某些特定的外层循环,避免繁琐的逻辑判断,代码简洁明了。
  2. 减少标志变量
    • 不需要通过额外的布尔变量来控制循环的退出条件,简化代码逻辑。
  3. 高效执行
    • 在某些场景下,用标签跳转可以减少冗余判断,提高代码效率。

缺点

  1. 降低可读性
    • 标签的逻辑不直观,尤其在复杂代码中,过多的标签会让人迷惑,破坏代码的结构化。
  2. 易引发逻辑混乱
    • 由于标签会跳过部分代码执行路径,容易出现不易察觉的逻辑漏洞或隐藏的 Bug。
  3. 违反结构化编程原则
    • 结构化编程强调通过条件判断和循环语句清晰地组织程序,而标签方法类似于 goto,可能破坏这种结构性。

适用场景

  1. 复杂多层嵌套循环
    • 在深层嵌套循环中,标签方法可以直接跳出多层循环而无需逐层判断。
      示例:搜索二维数组中符合条件的某个值时,找到后直接终止外层循环。
  2. 性能关键代码
    • 当需要快速跳出多层循环以减少不必要的判断时,标签方法可以提高效率。
      示例:图像处理或路径搜索等需要频繁遍历多维数据的场景。
  3. 有限的控制流调整
    • 当代码逻辑简单且标签使用得当时,可以通过标签减少额外的标志变量。

不适用场景

  1. 简单单层循环或逻辑清晰的代码
    • 对于简单逻辑,使用标签显得多余且冗长。
  2. 替代一般逻辑控制
    • 标签不能代替条件判断或函数调用,滥用标签可能导致难以维护的“意大利面条”代码(spaghetti code)。

经典案例

案例 1:查找二维数组中的第一个负数

public class LabelExample {
    public static void main(String[] args) {
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, -6},
            {7, 8, 9}
        };

        outer: // 定义外层标签
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] < 0) {
                    System.out.println("找到负数: " + matrix[i][j]);
                    break outer; // 直接跳出外层循环
                }
            }
        }
        System.out.println("搜索结束");
    }
}

输出:

makefile复制代码找到负数: -6
搜索结束

案例 2:跳过某些特定组合

java复制代码public class LabelContinueExample {
    public static void main(String[] args) {
        outer:
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                if (i == j) {
                    System.out.println("跳过 i=" + i + ", j=" + j);
                    continue outer; // 跳过当前外层循环迭代
                }
                System.out.println("i=" + i + ", j=" + j);
            }
        }
    }
}

输出:

css复制代码跳过 i=1, j=1
i=2, j=1
i=2, j=3
跳过 i=2, j=2
i=3, j=1
i=3, j=2
跳过 i=3, j=3

总结建议

  1. 标签方法的好处: 在嵌套循环层次较深时,能够有效控制程序流,避免复杂的标志变量判断。
  2. 标签方法的坏处: 使用不当会导致代码可读性差,特别是标签位置的跳转可能让人迷惑。
  3. 使用建议:
    • 只在复杂嵌套循环或性能要求较高的场景中使用标签。
    • 如果逻辑简单,优先通过 breakcontinue 的普通用法实现。
    • 避免多处定义标签,保持代码简洁清晰。

标签:scanner,分支,System,while,循环,println,out,public,结构
From: https://www.cnblogs.com/panghuhu-space/p/18628696

相关文章

  • 省选集训 day 1 数据结构杂题
    A比较套路的题目,第一次见还是有难度的。关于\(+1\)的更改,事实上是找到二进制下极长的末尾\(1\)段并进位。考虑使用Trie维护这个操作,相当于建立一颗从低位开始的Trie,然后swap儿子并进入swap后的新左子树递归操作。然后对于邻域的问题,一般考虑每个点单独维护其儿子,然后特......
  • C语言学生管理系统|结构体数组+文件操作+按照姓名排序
    也是第一次使用Markdown语法orz定义结构体structstudent{charname[10];charsex[5];intage;intnum;intscore[5];//需要储存五门课的成绩};structclass{structstudentst[50];//最大可存储50个学生信息intn;};主菜单函数......
  • RK3568平台开发系列讲解(中断及异常篇)Linux 中断系统中的重要数据结构
    ......
  • blog-结构与封装热应力仿真
    仿真场景结构放入某种温度环境较长时间:(1)管壳封装;(2)结构应力分布;(3)MEMS锚区比研究;仿真方法对于结构内外温度达到一致且该温度已知的情况,进行热应力分析时不需要引入传热接口。在固体力学中加入热膨胀子节点分析节后相对于参考温度的热应变。仿真原理热应力=杨氏模量*热膨胀系数*温度......
  • 使用Nuclia Understanding API处理非结构化数据的技术实践
    使用NucliaUnderstandingAPI处理非结构化数据的技术实践引言如今的企业和组织面临一个共同的挑战:如何有效处理和利用大量的非结构化数据。NucliaUnderstandingAPI通过自动索引和提取文本、视频、音频等非结构化数据,为用户提供优化的搜索结果和生成性答案。本文将探讨N......
  • git仓库多人协作新建分支 合并到主分支流程详解
    在多人协作的Git仓库中,新建分支并最终将其合并到主分支的流程是为了实现团队协作、提高代码的可管理性、确保代码质量,并且避免多人同时修改同一部分代码导致冲突。以下是这个流程的目的和具体步骤。目录1. 在 master 上新建一个分支2. 进行功能开发3. 合并功能分......
  • c语言结构体
    结构体   自定义的数据类型   就是由很多数据组合成的一个整体   每一个数据,都是结构体的成员定义struct结构体名字 { 成员1; 成员2; 。。。}struct GirlFriend{ charname[100]; intage;} 使用structGirlFriend gf1;strcpy(......
  • 功能结构图
    一、功能结构图1定义功能结构图就是按照功能的从属关系画成的图表,在该图表中的每一个框都称为一个功能模块。功能模块可以根据具体情况分得大一点或小一点,分解得最小功能模块可以是一个程序中的每个处理过程,而较大的功能模块则可能是完成某一个任务的一组程序。(百度定义)用通俗的话......
  • 数据结构实验
    (一)线性表1#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;multiset<int>ms;cin>>n;for(inti=1;i<=n;i++){intx;cin>>x;ms.insert(x);}intx;cin......
  • 数据结构实验
    (一)线性表1#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;multiset<int>ms;cin>>n;for(inti=1;i<=n;i++){intx;cin>>x;ms.insert(x);}intx;cin......