当前位置: 首页 > article >正文

Java 基本程序设计结构——从 C++ 到 Java

文章目录

  • 一个简单的java应用程序
  • 注释
  • 数据类型
  • 变量和常量
  • 运算符
  • 字符串
  • 输入和输出
  • 控制流程
  • 大数
  • 数组

一个简单的java应用程序

public class FirstSample {
    public static void main(String[] args) {
        System.out.println("Hello Java!");
    }
}
  • Java 区分大小写,main方法拼写必须正确,否则程序无法运行。public是访问修饰符,class表明程序内容在类中,Java 应用程序所有内容都在类里。
  • 类名命名规则宽松,但须以字母开头,不能用 Java 保留字。标准命名用骆驼命名法,源文件名要和公共类名相同且扩展名为.java。编译后生成同名.class文件,运行程序用java命令且不加.class扩展名。
  • 按 Java 语言规范,main方法须声明为public,不过早期有些编译器在非public时也能运行,Java 1.4 及以后版本强制要求。每个 Java 应用程序都必须有main方法,其标准格式固定。

C++注释:Java 中所有函数都是类的方法,main方法必须在一个外壳类中且是静态的,这点与 C++ 静态成员函数不同。和 C/C++ 一样,void表示方法无返回值,Java 中main方法正常退出无返回值,若要在终止程序时返回其他退出码,需用System.exit方法。

注释

  • 单行注释:最常用的是使用 “//”,注释内容从 “//” 开始到本行结尾。
  • 多行注释:当需要较长注释时,可在每行注释前标记 “//”,也能用 “/*” 和 “*/” 界定注释,将一段内容注释起来。
  • 文档注释:第三种注释以 “/**” 开始,以 “*/” 结束。

数据类型

Java 是强类型语言,每个变量都必须声明类型,共有 8 种基本类型,包括 4 种整型、2 种浮点类型、1 种字符类型char和 1 种表示真值的boolean类型,此外还有 “大数” 这种 Java 对象

整形

C++ 注释: C 和 C++ 中整型大小与目标平台相关,而 Java 的数值类型则与平台无关,且 Java 没有无符号整型形式。

浮点类型

image.png

char 类型

  • 原本用于表示单个字符,现有些 Unicode 字符需两个char值表示。

Unicode 和 char 类型

  • Java 采用 Unicode 编码,解释了码点、代码平面等概念,以及char类型在处理 Unicode 字符时的情况 。

boolean 类型

  • 只有falsetrue两个值,用于判定逻辑条件,不能和整数类型转换。

C++注释:在 C++ 中,数值甚至指针可以替代boolean值,值0相当于布尔值false,非0值相当于布尔值true 。在 Java 中,不能像 C++ 那样将整数表达式转换为布尔值。例如if (x = 0)在 Java 中不能通过编译,因为 Java 严格区分数据类型,不允许这种隐式的类型转换 。

变量和常量

声明变量

  • 声明变量时要先指定类型,后写变量名,每个声明以分号结束。

  • 变量名由字母或数字构成,以字母开头,区分大小写。

  • 不能用 Java 保留字,Java 9 后单下划线不能作变量名。

  • 虽然可一行声明多个变量,但逐一声明可提高可读性。

double salary;

变量初始化

  • 声明后需显式初始化变量,赋值时变量名在等号左侧,值在右侧,也可将声明和初始化放同一行。
  • 变量声明应靠近首次使用的地方。
  • 从 Java 10 开始,局部变量声明可使用var关键字,由系统根据初始值推断类型。

C++注释:C 和 C++ 区分变量声明与定义,int i = 10;是一个定义,而extern int i是一个声明;Java 不区分。

Java var 仅用于局部变量;C++ auto 用途更广,可用于局部变量、函数返回类型、模板编程等。

// double salary;
// salary = 65000.0;
double salary = 65000.0;

常量

  • final关键字指示常量,赋值后不能更改,常量名通常全大写。
  • 若希望常量在类的多个方法中使用,可用static final设置为类常量,其定义在main方法外部,若声明为public,其他类的方法也能使用。

C++注释const是 Java 保留关键字,但目前未使用,需用final定义常量。

public class Constants {
    final double CM_PER_INCH1 = 2.54;
    
    public static void main(String[] args) {
        final double CM_PER_INCH2 = 2.54;
    }
}

枚举类型

  • 当变量取值在有限集合内时,可自定义枚举类型。
  • 枚举类型包含有限个命名值,声明后可声明该类型的变量,变量只能存储给定的枚举值或特殊值null
enum Size { SMALL, MEDIUM, LAGRE, EXTRA_LAGRE};

运算符

算术运算符

  • 在 Java 中,“+、-、*、/” 分别表示加、减、乘、除运算。
  • 整数被 0 除会产生异常,浮点数被 0 除结果为无穷大或 NaN。

Java 运算的可移植性与浮点计算细节:可移植性是 Java 语言设计目标之一,但实现浮点数算术运算的可移植性较困难,因为不同处理器存储浮点数的精度有差异 。Java 虚拟机最初规范要求中间计算截断,后因会导致溢出且耗时,在默认情况下允许中间计算采用扩展精度。使用strictfp关键字标记方法或类,其中的浮点计算会采用严格的标准,使用严格计算可能产生溢出,而默认方式一般可避免溢出。

数学函数与常量

  • Math类包含各种数学函数,如计算平方根用sqrt方法。

  • Math类中的sqrt是静态方法。求幂用pow方法,floorMod可处理一些取模问题 。

数值类型之间的转换

image.png

上面展示了数值类型间的合法转换路径,如小范围整数类型可自动转换为大范围整数类型或浮点数类型,转换可能有精度损失 。

强制类型转换

  • 必要时int会自动转换为double,但doubleint可能丢失信息,需强制类型转换,格式为在圆括号中给出目标类型,紧跟待转换变量名。
  • 使用Math.round方法后仍需强制类型转换取整 。
double x = 9.997;
int nx1 = (int)x; // 9

int nx2 = (int)Math.round(x); // 10

C++注释:不要在boolean类型与任何数值类型之间进行强制类型转换,这样做能够防止出现一些常见的错误。只有在极少数情况下,才需要将布尔类型转换为数值类型 ,这时可以使用条件表达式 b?1:0

运算赋值和运算符

  • 在赋值中使用二元运算符简化代码,如x += 4等价于x = x + 4,运算符在=左边类型不同时会发生强制类型转换。

自增与自减运算符

  • n++使n值加 1,n--使n值减 1,有前缀和后缀两种形式,前缀形式会先完成加,后缀形式会使用变量原来的值。

关系和 boolean 运算符

  • ==检测相等性,!=检测不相等,还有<><=>=等关系运算符,&&||是逻辑运算符,遵循 “短路” 原则 。

三元运算符

  • 格式为condition ? expression1 : expression2,条件为真返回expression1的值,否则返回expression2的值 。

位运算符

  • 处理整型时可对二进制位操作,包括按位与(&)、按位或(|)、按位异或(^)、取反(~),还有左移(<<)和右移(>>>>>)运算符,移位操作时需注意数据类型和符号位 。

  • >>>会用 0 填充高位,这与>>不同,它会用符号位填充高位。不存在<<<运算符。

C++注释:在 C/C++ 里,右移运算符>>存在不确定性,无法保证是进行算术移位(扩展符号位)还是逻辑移位(填充 0)。而 Java 消这种不确定性。

括号与运算符优先级

C++注释:与 C 或 C++ 不同,Java不使用逗号运算符。不过,可以在for语句的第1部分和第3部分使用逗号分隔表达式列表。

image.png

字符串

Java 字符串是 Unicode 字符序列,由标准类库中的String类表示,用双引号括起来的都是String类实例,如String e = ""(空串)和String greeting = "Hello"

子串

  • String类的substring方法可从大字符串提取子串,该方法从索引 0 开始计数,第二个参数是不复制的第一个位置,子串长度为两参数差值。

C++注释:类似与 C 和 C++,Java字符串中的代码单元从 0 开始计数。

String greeting = "Hello";
String s = greeting.substring(0, 3); // Hel

拼接

  • 可使用+连接两个字符串,非字符串值会转换为字符串后拼接 。
  • Java 11 新增join方法,用界定符分隔多个字符串;repeat方法可重复字符串 。
int age = 13;
String rating = "PG" + 	age; // PG13

String all = String.join(" / ", "S", "M", "L", "XL"); // S/M/L/XL

String repeated = "Java".repeat(3); // JavaJavaJava		

不可变字符串

  • String类没有直接修改字符串中字符的方法,如需修改,通常提取保留子串再与替换字符拼接。

  • Java 中String类是不可变的,字符串存于公共存储池,共享带来的效率优势大于拼接等操作的低效。

greeting = greeting.substring(0, 3) + "p!";

C++注释: Java 字符串不是字符数组,实际类似char*指针,赋值操作会重新指向新字符串,原字符串由系统自动回收。C++ 中string对象也能自动管理内存,但 C++ 字符串的单个字符可修改,与 Java 不同 。

检测字符串是否相等

  • 可使用equals方法判断两个字符串内容是否相等,字符串变量或字面量都能参与比较,相等返回true,否则返回false
  • 若要不区分大小写比较,可使用equalsIgnoreCase方法。
  • 强调不能用==运算符检测字符串相等,因为==判断的是字符串是否存于同一位置,而内容相同的字符串副本可能在不同位置。
String greeting = "Hello";
if (greeting == "Hello") // probably true
if (greeting.substring(0, 3) == "Hel") // probably false

C++ 注释:在 Java 中需注意,Java 没有像 C++ 那样重载==运算符来检测字符串内容相等,其==更像指针比较;C 语言用strcmp函数比较字符串,Java 的compareTo方法类似,但使用equals方法更清晰 。

空串与 Null 串

  • 空串是长度为 0 的字符串,可通过str.length() == 0str.equals("")来判断一个字符串是否为空串。
  • null表示字符串变量未关联任何对象,检查字符串是否为nullif (str == null) 。同时检查字符串既非null又非空串,需使用if (str != null && str.length() != 0) ,在null值上调用方法会出错。

码点与代码单元

  • Java 字符串由char值序列组成,char类型采用 UTF - 16 编码表示 Unicode 码点,多数常用 Unicode 字符用一个代码单元表示,辅助字符需两个。
  • length方法返回的是代码单元数量,获取实际长度(码点数量)用codePointCount方法 。charAt方法返回指定位置的代码单元,获取指定位置码点用codePointAt方法。

String 类 API

  • Java 的String类包含 50 多个方法,实用性强、使用频率高。

阅读联机 API 文档

  • Java SE 9 API

构建字符串

  • 需要由较短字符串构建字符串,若用普通字符串拼接方式,每次拼接都会创建新的String对象,效率低且浪费空间。而StringBuilder类可避免该问题。
StringBuilder builder = new StringBuilder();
builder.append(ch);
builder.append(str);
String completedString = builder.toString();

StringBuilder类在 Java 5 中引入,其前身是StringBufferStringBuffer效率稍低,但允许多线程方式添加或删除字符。若所有字符串编辑操作都在单线程中执行,应使用StringBuilder,且这两个类的 API 相同。

输入和输出

读取输入

  • 在 Java 中,输出到控制台很容易,调用System.out.println即可,但读取 “标准输入流”System.in则需构造与System.in关联的Scanner对象(Scanner in = new Scanner(System.in);) 。
  • 可以使用Scanner类的多种方法读取输入,如nextLine读取一行,nextInt读取一个整数,nextDouble读取一个浮点数等。同时要注意导入java.util.*包。

因为输入是可见的,Scanner类不适用于读取密码,Java 6 引入Console类实现此目的,其readPassword方法返回的密码存于字符数组而非字符串,以增强安全性。

格式化输出

  • 使用System.out.print(x)可将数值x输出到控制台,按x类型允许的最大非 0 位数打印。

文件输入与输出

  • 文件读取:读取文件时,先构造Scanner对象,如Scanner in = new Scanner(Path.of("myfile.txt"), "UTF-8") ,若文件名含反斜杠需转义。

  • 文件写入:写入文件需构造PrintWriter对象,如PrintWriter out = new PrintWriter("myfile.txt", "UTF-8") ,若文件不存在则创建。可像使用System.out一样使用printprintln等方法进行输出。

控制流程

块作用域

  • 块(复合语句)由多条 Java 语句组成,用大括号括起,它定义了变量的作用域,一个块可以嵌套在另一个块中,但不能在嵌套的两个块中声明同名变量。

C++注释:在C++中,可以在嵌套块中重定义一个变量,在内存定义的变量会覆盖 外层定义的变量,Java 中不能允许这样做。

条件语句

  • if 语句:形式为if (condition) statement,当条件为真时执行语句,若要执行多条语句,需用大括号括起来形成块语句。
  • if/else 语句:形式是if (condition) statement1 else statement2,当条件为真执行statement1,否则执行statement2else部分是可选的。在多个if/else嵌套时,else与最邻近的if配对,使用大括号可使代码更清晰。

循环

  • while 循环:形式为while (condition) statement,条件为真时循环执行语句(可以是块语句),若开始时条件就为假,则循环一次也不执行。
  • do/while 循环:形式为do statement while (condition);,先执行语句,再检测循环条件,条件为真则重复执行,适用于至少要执行一次循环体的情况。

确定循环

  • for 循环的基本语法和使用方式,如for (int i = 10; i > 0; i--)
  • 在 for 语句第 1 部分声明的变量,作用域扩展到循环体末尾,且该变量不能在循环体外使用。
  • 不同 for 循环中可定义同名变量,for 循环是 while 循环的简化形式,两者可相互改写。

多重选择:switch 语句

  • 当处理多重选择时,使用 switch 语句比 if/else 结构更合适。
  • switch 语句从与选项值匹配的 case 标签开始执行,遇到 break 语句或 switch 结束处停止。若无匹配 case 标签且有 default 子句,则执行 default 子句。case 分支若缺少 break 语句会导致意外执行后续分支,存在风险。
  • case 标签可以是 char、byte、short、int 的常量表达式,从 Java 7 开始还可以是字符串字面量。使用枚举类型时,switch 表达式可直接得出枚举值 。

中断控制流程的语句

  • Java 中保留 goto 关键字但未使用其作为程序设计语句,因为随意使用 goto 可能使程序逻辑混乱,不过在某些复杂情况下,其他语言(如 C)可能会用到类似功能。
  • break 语句用于跳出循环或 switch 语句,可带标签用于跳出多重嵌套循环;continue 语句用于中断当前循环体剩余部分,跳到循环首部继续执行 。

大数

当基本整数和浮点数精度无法满足需求时,可使用java.math包中的BigIntegerBigDecimal类。BigInteger实现任意精度的整数运算,BigDecimal实现任意精度的浮点数运算。

数组

声明数组

  • 数组用于存储相同类型值的序列,是一种数据结构,通过整型下标访问元素。
  • 声明数组变量时需指出数组类型(数据元素类型紧跟[])和变量名,如int[] a;
  • 使用new操作符创建数组,如int[] a = new int[100]; ,数组长度不必是常量。
  • 可采用简写形式在创建数组时初始化,如int[] smallPrimes = { 2, 3, 5, 7, 11, 13 }; ,还能重新初始化数组而无需创建新变量。
  • Java 允许创建长度为 0 的数组,其与null不同。

访问数组元素

  • 数组元素下标从 0 开始,创建数组后可填充元素。
  • 数字数组元素初始值为 0,boolean数组为false,对象数组为null
  • 可通过array.length获取数组元素个数。
  • 访问数组时若下标越界,会引发 “array index out of bounds” 异常。

for each 循环

  • 功能很强的循环结构,用于依次处理数组或实现了Iterable接口的集合中的每个元素,无需考虑下标值。语法为for (variable : collection) statement
for (int element : a)
    System.out.println(element);

数组拷贝

  • 直接将一个数组变量赋值给另一个数组变量,两个变量将引用同一个数组。
  • 若要将一个数组的所有值拷贝到新数组,需使用Arrays类的copyOf方法 ,该方法也常用于增加数组大小。
  • 若新数组长度大于原数组,数值型元素额外部分赋值为 0,布尔型赋值为false;若新数组长度小于原数组,则只拷贝前面的值 。
int[] LuckNumbers = smallPrimes;
LuckNumbers[5] = 12;

int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);

LuckyNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);

image.png

C++注释:Java 数组与 C++ 堆栈上的数组不同,Java 数组类似于在堆上分配的数组指针。且 Java 的[]运算符预定义了越界检查,没有指针运算 。

命令行参数

  • 每个 Java 应用程序都有一个带String[] args参数的main方法,该参数是一个字符串数组,用于接收命令行上指定的参数。

C++注释:在 Java 应用程序的main方法中,args数组用于接收命令行参数,程序名并不存储在args数组中。

数组排序

  • 使用Arrays类的sort方法可对数值型数组进行排序,该方法采用优化的快速排序算法。
Array.sort(result);

多维数组

  • 多维数组通过多个下标访问元素,适用于表示表格或复杂排列的数据。
double[][] balances;
balances = new double[YEARS][RATES];

int[][] magicSquare = { 
    {16, 3, 2, 13}, 
    {5, 10, 11, 8}, 
    {9, 6, 7, 12}, 
    {4, 15, 14, 1} };

不规则数组

  • Java 实际上没有真正的多维数组,而是由数组组成的数组。

C++注释: Java 中二维数组的声明方式double[][] balances = new double[10][6];

不同与 C++ 中,double balances[10][6];的声明方式与 Java 不同;也不同与(*balances)[6] = new double[10];而类似于

double** balances = new double*[10];
for (i = 0; i < 10; i++) 
	balances[i] = new double[6];
```**加粗样式**

http://www.kler.cn/a/577634.html

相关文章:

  • 《AI大模型专家之路》No.2:用三个模型洞察大模型NLP的基础能力
  • python从入门到精通(二十六):python文件操作之Word全攻略(基于python-docx)
  • 算法006——和为S 的两个数
  • 智能合约中权限管理不当
  • 系统架构设计师—系统架构设计篇—微服务架构
  • 基于PyTorch的深度学习3——基于autograd的反向传播
  • 恢复IDEA的Load Maven Changes按钮
  • dify通过ollama简单配置deepseek模型
  • 如何禁用移动端页面的多点触控和手势缩放
  • 【Gaussian Model】高斯分布模型
  • 新手学习爬虫的案例
  • Centos8部署mongodb报错记录
  • Linux 基础---重定向命令(>、>>)、echo
  • 正版Windows10/11系统盘制作详细教程
  • Linux设备驱动开发之摄像头驱动移植(OV5640)
  • 尚硅谷爬虫note14
  • 【后端开发面试题】每日 3 题(九)
  • PDF 分割工具
  • 请谈谈 HTTP 中的重定向,如何处理 301 和 302 重定向?
  • 在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法总结