包机制、文档注释javaDoc、用户交互Scanner20241223

包机制20241223

点击src 打开设置 点击外观 取消勾选压缩空的中间软件包、平展软件包

image-20241223103844568

创建包

点击src 点击新建,点击软件包

image-20241223103754420

输入新建包名 com.pangHuHuStudyJava

用别的包里的方法,要先导入包,如果没有导入,可以按住出错的地方按alt+enter.

import java.util.Date;

image-20241223105428560

在operator.demo02用base包用Demo02_data_radix_conversion

import com.pangHuHuStudyJava.base.Demo02_data_radix_conversion;//导入base包中的Demo02_data_radix_conversion类
import com.pangHuHuStudyJava.base.*;//导入base包中的所有类

image-20241223105830622

避免类名重复

你导入的 Demo05_this 类确实是在 com.pangHuHuStudyJava.base 包中定义的,但是错误信息提示的是你在 com.pangHuHuStudyJava.operator 包中已经定义了一个名为 Demo05_this 的类。这种情况在 Java 中称为 命名冲突,即虽然 Demo05_this 类在不同的包中,但由于同名类会引发编译器的冲突,所以无法正确区分。

解决方案:

1. 更改类名

  • 最直接的解决方法是 重命名 com.pangHuHuStudyJava.operator 包中的 Demo05_this,例如可以命名为 Demo05_thisOperator

  • 这样,com.pangHuHuStudyJava.base.Demo05_thiscom.pangHuHuStudyJava.operator.Demo05_thisOperator 就不会发生命名冲突。

    示例代码:

    com.pangHuHuStudyJava.operator 包中的类:

    java复制代码package com.pangHuHuStudyJava.operator;
    
    // 改名为 Demo05_thisOperator,避免与 base 包中的 Demo05_this 类冲突
    public class Demo05_thisOperator {
    public static void main(String[] args) {
      System.out.println("This is the Demo05_thisOperator class in the operator package.");
    }
    }
    

    com.pangHuHuStudyJava.base 包中的类:

    package com.pangHuHuStudyJava.base;
    
    public class Demo05_this {
    public static void main(String[] args) {
      System.out.println("This is the Demo05_this class in the base package.");
    }
    }
    

    com.pangHuHuStudyJava.operator 中导入并使用 base 包中的类:

    package com.pangHuHuStudyJava.operator;
    
    import com.pangHuHuStudyJava.base.Demo05_this; // 导入 base 包中的 Demo05_this 类
    
    public class Demo05_thisOperator {
    public static void main(String[] args) {
      System.out.println("This is the Demo05_thisOperator class in the operator package.");
    
      // 创建 base 包中的 Demo05_this 类的对象
      Demo05_this demo = new Demo05_this();
      demo.main(args);  // 调用 base 包中 Demo05_this 类的 main 方法
    }
    }
    

    解决思路:

    • 避免重名:最简单和推荐的方式是,避免在同一个包中出现重名的类。
    • 分包管理:确保不同功能的类被放入不同的包中,这有助于减少命名冲突的风险,并使项目结构更清晰。

2. 分清导入路径

  • 确保在 com.pangHuHuStudyJava.operator 包中使用 com.pangHuHuStudyJava.base 包中的类时,能正确区分不同包的类。如果没有冲突,导入路径应当是可以正常使用的。

    示例 1:使用完全限定名解决冲突

    假设你有两个同名的类,分别位于不同的包中:

    1. com.pangHuHuStudyJava.base 包中的类:

    package com.pangHuHuStudyJava.base;
    
    public class Demo05_this {
    public void printMessage() {
      System.out.println("This is the Demo05_this class from the base package.");
    }
    }
    

    2. com.pangHuHuStudyJava.operator 包中的类:

    package com.pangHuHuStudyJava.operator;
    
    public class Demo05_this {
    public void printMessage() {
      System.out.println("This is the Demo05_this class from the operator package.");
    }
    }
    

    3. 在 com.pangHuHuStudyJava.operator 包中使用 com.pangHuHuStudyJava.base.Demo05_this 类:

    com.pangHuHuStudyJava.operator 包中,如果你想使用 com.pangHuHuStudyJava.base.Demo05_this 类,直接使用 完全限定名 来避免冲突:

    package com.pangHuHuStudyJava.operator;
    
    public class Demo05_thisOperator {
    public static void main(String[] args) {
      System.out.println("This is the Demo05_thisOperator class in the operator package.");
    
      // 使用完全限定名调用 base 包中的 Demo05_this 类
      com.pangHuHuStudyJava.base.Demo05_this demoFromBase = new com.pangHuHuStudyJava.base.Demo05_this();
      demoFromBase.printMessage();  // 输出:This is the Demo05_this class from the base package.
    
      // 使用 operator 包中的 Demo05_this 类
      Demo05_this demoFromOperator = new Demo05_this();
      demoFromOperator.printMessage();  // 输出:This is the Demo05_this class from the operator package.
    }
    }
    

文档注释20241223

/** 注释内容*/

javaDoc生成文档

package com.pangHuHuStudyJava.operator;
/**
 * @author:pangHuHu
 * @version:1.0
 * @since:1.8
 */
public class JavaDoc {
    Sting name;
    /**
     * @author CAL
     * @param name
     * @throws Exception
     */
    public solution(String name) throws Exception{
        return name;
    }
}

用CMD做JavaDoc编码

Microsoft Windows [版本 10.0.22631.4602]
(c) Microsoft Corporation。保留所有权利。
D:\download\code\JavaSE\basic_demo\src\com\pangHuHuStudyJava\operator>md javaDoc_data_byCMD
D:\download\code\JavaSE\basic_demo\src\com\pangHuHuStudyJava\operator>dir
驱动器 D 中的卷是 新加卷
卷的序列号是 5073-C048
D:\download\code\JavaSE\basic_demo\src\com\pangHuHuStudyJava\operator 的目录
2024/12/23  16:45    <DIR>          .
2024/12/23  10:41    <DIR>          ..
2024/12/23  10:55             1,227 Demo01.java
2024/12/23  11:00             2,250 Demo02.java
2024/12/23  10:41               413 Demo03.java
2024/12/23  10:41               414 Demo04.java
2024/12/23  11:07               219 Demo05_this.java
2024/12/23  16:42               355 JavaDoc.java
2024/12/23  16:45    <DIR>          javaDoc_data_byCMD
         6 个文件          4,878 字节
         3 个目录 183,161,597,952 可用字节
D:\download\code\JavaSE\basic_demo\src\com\pangHuHuStudyJava\operator>javaDoc -d javaDoc_data_byCMD -encoding UTF-8 -charset UTF-8 JavaDoc.java
正在加载源文件JavaDoc.java...
正在构造 Javadoc 信息...
标准 Doclet 版本 1.8.0_181
正在构建所有程序包和类的树...
正在生成javaDoc_data_byCMD\com\pangHuHuStudyJava\operator\JavaDoc.html...
JavaDoc.java:14: 警告: 没有 @return
public String solution(String name) throws Exception{
            ^
正在生成javaDoc_data_byCMD\com\pangHuHuStudyJava\operator\package-frame.html...
正在生成javaDoc_data_byCMD\com\pangHuHuStudyJava\operator\package-summary.html...
正在生成javaDoc_data_byCMD\com\pangHuHuStudyJava\operator\package-tree.html...
正在生成javaDoc_data_byCMD\constant-values.html...
正在构建所有程序包和类的索引...
正在生成javaDoc_data_byCMD\overview-tree.html...
正在生成javaDoc_data_byCMD\index-all.html...
正在生成javaDoc_data_byCMD\deprecated-list.html...
正在构建所有类的索引...
正在生成javaDoc_data_byCMD\allclasses-frame.html...
正在生成javaDoc_data_byCMD\allclasses-noframe.html...
正在生成javaDoc_data_byCMD\index.html...
正在生成javaDoc_data_byCMD\help-doc.html...
1 个警告
D:\download\code\JavaSE\basic_demo\src\com\pangHuHuStudyJava\operator>

javaDoc -d javaDoc_data_byCMD -encoding UTF-8 -charset UTF-8 JavaDoc.java

用IDEA怎么生成javaDoc

第一步:选择生成JavaDoc文档的范围,我只对一个源文件生成Doc,所以选择文件。

第二步:输出目录最好新建一个文件夹,比较有条理和整洁

第三步:区域设置,决定文档的语言,简体中文就是zh_CN、繁体(台湾)zh_tw、繁体(香港)zh-hk、英语(香港)en-hk、英语(美国)en-us、英语(英国)en-gb、英语(全球)en-ww

第四步:其他命令行参数:如果区域设置为中国,参数一般为-encoding UTF-8 -charset UTF-8

第五步:设置完成后点击确定即可生成Doc文档

image-20241223170057276

image-20241223165821299

用户交互Scanner 20241223

Scanner对象

◆之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入java.util.Scanner 是Java5 的新特征,我们可以通过Scanner 类来获取用户的输入。

◆基本语法:

Scanner s=new Scanner(System.in);

◆通过 Scanner 类的 next()与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext()与 hasNextLine()判断是否还有输入的数据。

package com.pangHuHuStudyJava.canner;
import java.util.Scanner;
public class Demo01 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     System.out.println("使用next方法接收:");
     //判断用户有没有字符串输入
     System.out.println(scanner.hasNext());
     if (scanner.hasNext()){
         String str = scanner.next();
         System.out.println("输入的内容为:" + str);
     }
     else {
         System.out.println("输入完毕。");//
     }
     System.out.println(scanner.hasNext());
     scanner.close();//IO流用完就关闭
 }
}

输入: 你好,hello word +enter

输出:

true
输入的内容为:你好,hello
true

输入:你好,hello word^D

输出:

false
输入完毕。
false

我知道我的理解偏差在哪里,在于阻塞的语句判断错误,阻塞的语句在scanner.hasNext();而不是String str = scanner.next

阻塞发生的位置

  • 真正的阻塞发生在 scanner.hasNext()
    • scanner.hasNext() 会尝试从输入流中读取数据以检查是否有有效输入。
    • 如果输入流中没有可用数据(用户尚未按下 <Enter> 或未结束输入),scanner.hasNext() 会阻塞,等待用户操作。
  • scanner.next() 的行为:
    • 在进入 scanner.next() 前,scanner.hasNext() 必须已经返回 true
    • 由于 scanner.hasNext() 确保了输入流中有有效数据,scanner.next() 直接从输入流中读取数据,不会再阻塞。

阻塞的本质

阻塞是程序在等待某个外部条件满足后才能继续执行的状态。在 Scanner.hasNext() 中,阻塞点是在输入流没有任何可供读取的数据时:

  • 程序暂停hasNext()直到有数据输入或者流结束
  • 阻塞结束后,程序会继续执行下面的代码。

Enter 的影响

  1. 按下 Enter 时的行为:

    • 用户输入的内容被提交到输入流中。

    • 如果输入行中存在有效内容(非空白字符)hasNext() 检测到这些内容后,返回 true阻塞结束

    • 阻塞结束的条件是输入流有数据而不是流结束。

  2. 如果输入为空行:

    • 按下 Enter 后,如果行中没有有效内容,hasNext() 并不会返回 false,因为输入流未结束。
    • 阻塞会继续,直到用户输入有效内容或者输入流被关闭
  3. 阻塞结束后的行为:

    • 程序继续执行,进入 if 块读取内容。确保了有效内容——hasnext()变为true(否则一直阻塞)
    • 注意:Enter 只是提交当前行的数据,并不会关闭输入流所以 hasNext() 不会返回 false

Ctrl+D 的影响

  1. 按下 Ctrl+D 时的行为:
    • Ctrl+D 表示用户明确结束输入流。
    • 此时,Scanner 认为输入流结束了不再有任何数据可供读取。
  2. 对阻塞的影响:
    • Ctrl+D 立即结束阻塞无论输入流中是否有数据。
    • hasNext() 返回 false程序进入 else
  3. 为什么阻塞结束?
    • 按下 Ctrl+D 后,输入流被标记为关闭(EOF,End of File),Scanner 无需等待用户进一步输入。

关键区别总结

用户行为 阻塞影响 是否结束阻塞 hasNext() 返回值 输入流状态
输入有效内容 + Enter 数据提交,阻塞结束 true 打开
输入空行 + Enter 阻塞继续,等待更多输入 - 打开
按下 Ctrl+D 输入流结束,阻塞结束 false 关闭
package com.pangHuHuStudyJava.canner;
import java.util.Scanner;
public class Demo01 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     System.out.println("使用next方法接收:");
     //判断用户有没有字符串输入
     System.out.println(scanner.hasNext());
     if (scanner.hasNext()){
         String str = scanner.next();
         System.out.println("输入的内容为:" + str);
     }
     else {
         System.out.println("输入完毕。");//
     }
     System.out.println(scanner.hasNext());
     scanner.close();//IO流用完就关闭
 }
}
使用next方法接收:
true
nihao world
输入的内容为:nihao
true

进程已结束,退出代码为 0 
package com.pangHuHuStudyJava.canner;
import java.util.Scanner;
public class Demo02 {
 public static void main(String[] args) {
     Scanner scanner = new Scanner(System.in);
     System.out.println("用nextline方法");
     System.out.println(scanner.hasNextLine());
     if(scanner.hasNextLine()){
         String line = scanner.nextLine();
         System.out.println(line);
     }
     else {
         System.out.println("输入完毕");

     }
     System.out.println(scanner.hasNextLine());
 }
}
用nextline方法
nihao dwoda
true
nihao dwoda
asdas
true

为什么第二段代码,要输出两次才终止,第一段输入一次就行了

这种行为差异与 next()nextLine() 的工作方式有关。它们对输入流的处理方式不同,导致了程序执行的差异。


第一段代码行为分析(next()

流程

  1. scanner.hasNext()
    
    • 检查输入流中是否存在有效单词。用户输入 nihao world 并按 Enter,这行内容被提交。
    • hasNext() 发现有有效单词(nihao返回 true=
  2. scanner.next()
    
    • 读取输入流的第一个单词(nihao),光标移动到 world 之后。
    • world 仍然保留在输入流中。
  3. 第二次调用

    scanner.hasNext()
    
    • 由于 world 尚未被读取hasNext() 返回 true

终止条件

  • 因为输入流中还有数据,scanner.hasNext() 返回 true,不会阻塞。
  • 第二段代码会等待输入(见下方分析),这是核心区别。

第二段代码行为分析(nextLine()

流程

  1. scanner.hasNextLine()
    
    • 检查输入流中是否存在下一行。用户输入 nihao dwoda 并按 Enter,这行被提交。
    • hasNextLine() 返回 true,因为输入流中有一整行数据。
  2. scanner.nextLine()
    
    • 读取整行数据 nihao dwoda光标移动到该行末尾。
  3. 第二次调用

    scanner.hasNextLine()
    
    • 程序等待新的输入,因为 nextLine() 已经清空了当前行的数据。
    • 用户需要输入新的内容(例如 asdas),然后按 Enter,程序继续运行。

关键区别

  1. 输入读取方式

    • next() 只读取一个有效单词剩余的输入数据仍保留在流中因此不需要额外输入就能继续运行
    • nextLine() 读取整行数据清空该行后,程序等待新的输入
  2. hasNext()hasNextLine() 的行为

    • hasNext() 检查是否存在未被读取的有效单词,因此只需要一次输入
    • hasNextLine() 检查是否存在未被读取的整行,读取完一行后需要额外输入
  3. 阻塞行为

    • 第一段代码的 hasNext() 不会阻塞,因为 world 仍然在输入流中
    • 第二段代码的 hasNextLine() 会等待用户提供新的输入行

为什么第二段代码需要额外输入才能终止?

  • nextLine() 在读取整行数据后清空了当前输入流的内容,程序需要新的输入行来继续运行。
  • 因此,用户需要输入额外的内容(如 asdas)并按 Enter 提交,才能使程序继续执行后面的逻辑。

总结

  • next() 适用于按单词读取输入,剩余数据仍保留在流中,减少了额外的输入需求。
  • nextLine() 每次读取并清空整行输入,因此需要新的输入才能继续运行。
  • 程序终止与否的关键在于输入流是否有剩余数据,以及输入方法对流的处理方式。
package com.pangHuHuStudyJava.canner;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);
  System.out.println("使用next方法接收:");
  //判断用户有没有字符串输入
  System.out.println(scanner.hasNext());//可不可以,和你在一起 趁我还没有过保质期
  if (scanner.hasNext()){               //光标此时在第一个可这里  肯定是有效字符串输入的 hasNext()是True
      String str = scanner.next(); //第一个字符到第一个空格  把可不可以,和你在一起压进str 光标现在在趁字处,hasNext()仍是true
      System.out.println("输入的内容为:" + str);//输出str
  }
  else {
      System.out.println("输入完毕。");// hasNext()是True 不执行else语句块
  }
  System.out.println(scanner.hasNext());//如第10行所述,此时光标在趁字处,仍有有效字符,hasNext()是true
  String str_1 = scanner.next();//把趁字后面的字符串压进str1
  System.out.println(str_1);//输出str_1
  scanner.close();//IO流用完就关闭
}
}

使用next方法接收:
可不可以,和你在一起 趁我还没有过保质期
true
输入的内容为:可不可以,和你在一起
true
趁我还没有过保质期

package com.pangHuHuStudyJava.canner;

import java.util.Scanner;

public class Demo02 {
public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);//创建新对象
  System.out.println("用nextline方法");
  System.out.println(scanner.hasNextLine());//阻塞,等待输入,可不可以,和你在一起。
  if(scanner.hasNextLine()){   //按下enter,有效line输入了,光标此时在第一个可字这里。hasNextLine()是True
      String line = scanner.nextLine();//把输入的 可不可以,和你在一起。压进line中. 此时光标在。句号后
      System.out.println(line);//输出line
  }
  else {
      System.out.println("输入完毕");
  }
  System.out.println(scanner.hasNextLine());//此时光标在。句号后不知道是不是有有效Line.重新进入阻塞状态。输入 趁我还没过保质期  
  String line_1 = scanner.nextLine();//把趁我还没过保质期压进line_1中  光标在期后
  System.out.println(line_1);//输出line_1
}
}

用nextline方法
可不可以,和你在一起。
true
可不可以,和你在一起。
趁我还没过保质期
true
趁我还没过保质期

package com.pangHuHuStudyJava.canner;
import java.util.Scanner;
public class Demo03 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double sum=0;
        int num=0;
        while(scanner.hasNext())
        {
            double temp=scanner.nextDouble();
            sum+=temp;
            num++;
            System.out.println("你输入的第"+num+"个数值是:"+temp+"。总值为:"+sum);
        }
        System.out.println("输出结束。"+"你输入了"+num+"个数。"+"它们的平均值是:"+sum/num);
    }
}

10
你输入的第1个数值是:10.0。总值为:10.0
20
你输入的第2个数值是:20.0。总值为:30.0
40
你输入的第3个数值是:40.0。总值为:70.0
30
你输入的第4个数值是:30.0。总值为:100.0
^D
输出结束。你输入了4个数。它们的平均值是:25.0

or 空格键做分割符

10 20 30 40
你输入的第1个数值是:10.0。总值为:10.0
你输入的第2个数值是:20.0。总值为:30.0
你输入的第3个数值是:30.0。总值为:60.0
你输入的第4个数值是:40.0。总值为:100.0
^D
输出结束你输入了4个数。它们的平均值是:25.0

关键点回顾

  1. next()nextLine()
    • next()
      • 按单词读取,遇到空格、回车等分隔符停止读取。
      • 剩余的数据仍保留在输入流中。
    • nextLine()
      • 读取整行,包括空格,直到遇到回车符为止。
      • 当前行的数据会被清空。
  2. hasNext()hasNextLine()
    • hasNext():检查输入流中是否有有效单词
    • hasNextLine():检查输入流中是否有整行输入
  3. 阻塞行为
    • hasNext()hasNextLine() 在无输入时会阻塞,等待用户输入。
    • 阻塞状态下,只有按下 EnterEOF (如 Ctrl+D),程序才会继续执行。

代码学习建议

  • 你的代码中已经尝试了多种场景(单词读取、行读取、数值处理),非常有助于理解输入流的各种操作。

  • 进一步的实验可以尝试:

    1. 读取特定格式的数据

      java复制代码while (scanner.hasNextDouble()) {
          double value = scanner.nextDouble();
          System.out.println("读取到的数值:" + value);
      }
      
    2. 异常处理:处理用户输入的非法字符或格式错误。

    3. 结合文件输入:将 Scanner 应用到文件中,处理大规模数据。


结论

通过这些代码实验,你已经掌握了 Scanner 的基础用法以及它在不同场景下的行为差异。这种深入分析和反思的学习方法非常棒,继续加油!如有其他问题,随时交流! 😄

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("你输入的不是整数");
        }
        System.out.println("请输入小数");
        if(scanner.hasNextFloat()){
            f=scanner.nextFloat();
            System.out.println("你输入的小数是:"+f);
        }
        else{
            System.out.println("你输入的不是小数");
        }
        scanner.close();
    }
}

代码分析

  1. 功能实现
    • scanner.hasNextInt():检查输入是否是一个整数。
    • scanner.nextInt():获取用户输入的整数。
    • scanner.hasNextFloat():检查输入是否是一个浮点数。
    • scanner.nextFloat():获取用户输入的浮点数。
  2. 逻辑流程
    • 首先提示用户输入整数,若输入正确,读取并打印;否则提示错误。
    • 然后提示用户输入小数,若输入正确,读取并打印;否则提示错误。
  3. 输入错误处理
    • 如果输入格式不匹配,例如在输入整数时输入了非数字字符,会进入 else 块提示用户错误。
posted @ 2024-12-23 22:57  panghuhu~  阅读(84)  评论(0)    收藏  举报