《C++转JAVA快速入手系列》:基本通用语法篇

文章目录

《C++转JAVA快速入手系列》:基本通用语法篇

系列导读 : 这个系列就如标题所示,专为有一定C++基础想要学习java或具备一定基础的读者设计,旨在帮助快速掌握要点或进行知识梳理,对于许多语法上相同的地方只会一笔带过,重点强调不同之处,方便各位抓住重点,提高效率去进行记忆以及理解。

1、Java语言的简要介绍

Java语法是基于前辈C++语法的精简优化去除了头文件、指针运算、结构体、联合体、操作符重载和虚基类等复杂特性。与此同时,Java的开发环境也比大多数编程语言更加完善。

1.1、Java中的main方法

  • 在C++中的''函数 '',到了Java中更习惯被称作''方法 ''

示例演示:

java 复制代码
public class HelloWorld{
 public static void main(String[] args){
 System.out.println("Hello,world");
 }
}

如上就是java中编写的打印helloworld的代码,如果你对此一头雾水,也不要担心,下面会进行必要的解读:

首先java与C++一样是一门面向对象的语言,而java对其更为贯彻,用一句流传的话叫做:在Java的世界里,一切皆为对象 。因此,你看到的这个main方法也是被名为HelloWorld的类 所包括在内,不仅如此,Java并没有 像C++中一样有所谓的全局变量/函数 ,你如果在类外写任何 变量,常量,方法等都会报错

对于有C++基础的人来说,这段代码中的一部分关键词并不陌生,在这里就不给出这些关键字在java中的细微差别了,我们以后再进行对比。

  • String[] args :这是main方法的参数
    其中String[]表示这是一个字符串数组(String类型的数组)。
    args 是这个数组参数的名称(变量名)
    作用 :它允许在命令行 运行程序时向程序传递参数

  • System.out.println : 这是Java中常用于打印的函数
    System : 是 Java 内置的一个类,提供对系统相关功能的访问。
    out : 是 System 类中的一个静态成员变量(字段),它是一个 PrintStream 对象,通常代表标准输出流(控制台)。
    println : 是 PrintStream 类的一个方法。
    作用:System.out.println(...) 用于将括号内的内容打印(输出)到标准输出(通常是控制台),并在输出结束后换行。

如果你对面的解释还留有一些疑问,那也不用担心,这里只需知道个大概即可接着学习

1.2 、java程序的运行

Java是一门半编译型,半解释型 语言,javac 先将源文件 进行编译 ,得到对应的.class 文件,该文件是由字节码组成 的,面向JVM 的文件,然后启动java虚拟机 来运行.class文件,此时虚拟机也就是JVM 会将字节码转换成平台能够理解的形式运行

由此可见,java程序的运行离不开这些工具,所以要先装好JDK (即java开发工具包),JDK中就包含了javac 和 java工具,java程序最终是在JVM(java虚拟机)中运行的

我们对此反观C++(纯编译型语言)经过的处理是:预处理->编译->汇编->链接,它的源文件 直接编译成机器码可执行文件 ,运行时不需解释或虚拟机 。编译过程生成平台相关二进制文件 ,执行效率高 ,但缺乏跨平台性(需重新编译)

  • 而Java只需要编译一次,就可以在任意JVM中运行,所以Java中还有一句话叫做:一次编译,到处运行

接下来我们来区分一下JDK、JRE、JVM之间的关系,这也是一道面试题

  • JDK(Java Development Kit):Java开发工具包,提供给Java程序员使用,包含了
    JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。
  • JRE(Java Runtime Environment):Java运行时环境,包含了JVM,Java基础类库。是使用Java语言编写程序运行的所需环境。
  • JVM:Java虚拟机,运行Java代码

可以简化为 JDK = JRE + 开发工具集(比如javac)
JRE = JVM + JavaSE标准类库

1.3、注释

Java 中的注释主要分为以下三种:

  • 单行注释 //
  • 多行注释 /* */
  • 文档注释 /** */

这里我们主要介绍文档注释:

  • 文档注释一般用于方法和类 之上描述方法和类的作用 ),可以被javadoc工具解析 ,生成一套以网页文件形式 体现的程序说明文档

注意:单行和多行注释并不像文档注释一样可以参与编译

1.4、标识符

何为标识符,直接给出定义:

  • 即类名、方法名、变量名的统称

标识符的硬性要求:(不满足会报错)

  • 只能由字母、数字、下划线、$ (美元符号)组成
  • 不能以数字开头,不能与关键字同名,严格区分大小写

1.5、字面量和字面常量

字面常量 :指的就和C++中的常量一样,在C++中用的是const修饰,在java中用的是final 修饰
字面量:C++中的类似,只不过java中不能像C++中可以用户自定义字面量

1.6、数据类型

  • Java中的数据类型分为两类:基本数据类型引用数据类型

基本数据类型:有四类,八种

  • 整型: 与C++相比,多了一个byte(字节型)占1字节,去除了longlong 超长整型
  • 浮点型 :与C++相同
  • 字符型 :char 的所占字节变成了 2字节 ,且在java中的char类型只能是字符不能是字符串,详情后面讲
  • 布尔型:与C++相比类型名发生了变化,变成了boolean

引用数据类型:

  • 在Java中为以上八种基础类型对应配了八种引用类型 也就是包装类
基本类 引用(包装)类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

这也呼应了java那句万物皆为对象的话,在纯面向对象的世界里,有很多设计的地方要求必须是对象:泛型,集合类中HashMap等储存的是对象,统一的方法调用等等,所以才会给这些基础类型有对应的升级。

1.7、变量

Java中的变量和C++中的含义相同,以下仅对于具体的使用之处不同之处进行说明

  • 基本类型 的变量定义后 如果不初始化去访问会报错
  • 想要知道某种基础类型 变量的最大值或最小值 ,使用它们的对应引用类型 进行访问,这些包装类中提供的静态成员常量名都是相同的:MIN_VALUEMAX_VALUE
java 复制代码
System.Out.println(Long.MIN_VALUE);
System.Out.println(Long.MAX_VALUE);
System.Out.println(Short.MIN_VALUE);
System.Out.println(Short.MAX_VALUE);
  • Java中的boolean类型int类型不能相互转换 ,不存在1表示true,0表示false这种说法

1.8、类型转换

在java中参与运算 数据类型不一致 时,就会进行类型转换,与C++类似,也分隐式类型转换强制类型转换,但因为没有指针的原因,java中的类型转换并没有C++那么复杂。

【由于转化的情况比较复杂多端,所以不和C++进行对比来进行学习】

1.8.1隐式类型转换

java隐式类型转换 主要发生在基本数据类型之间

主要分为以下四类

  1. 数值类型提升:在表达式中国,较小范围的数值类型会自动提升为较大的范围类型例如:
    • byte、short、char在运算中自动提升为int
    • int 可以提升为long、float、double
    • float 可以提升为double
  2. 赋值转换 : 在赋值操作中,如果目标类型范围更大,则被赋值的变量会自动转化
    例如:
java 复制代码
long 1 = 100;
double d = 3.14f //float隐式转化为double
  1. 对象类型向上转型: 子类对象可以自动转换为父类类型(向上转型)
    例如:
java 复制代码
class Animal{}
class Dog extends Animal{}
Animal animal = new Dog(); //此时new出来的Dog类型的对象隐式类型转换为Animal类型
  1. 字符串拼接:非字符串类型在连接字符串时自动转换为字符串
    例如:
java 复制代码
String s = "Value: " + 5;

还有一种时编译时,编译器可能将常量值自动转化

1.8.2 强制类型转换(显示)

顾名思义需要程序员进行强制类型转换的语法 (type) 来进行操作

  1. 数值类型缩小:当较大范围 的类型转换范围较小 的类型时,使用强制类型转换,这也意味着可能丢失精度

  2. 对象类型向下转型:父类 引用转换为子类 类型(向下转型),但需运行时检查(可能会抛出异常)

    例如:

java 复制代码
Animal animal = new Dog();
Dog dog = (Dog)animal ; 
  1. 字符和数值转换:例如char 到 int 的转换
  2. 布尔类型不参与转换:Java中boolean类型不能转换为其他类型

以上便是所有数据类型转换的情况,其中关于引用类型(对象)的转型的具体情况我们在后面的章节再细说

2、运算符

Java和C++ 在算数运算符、关系运算符、逻辑运算符、位运算符、以及赋值运算符等方面用法高度相似,以下仅介绍不同之处

  • 在关系运算符中(> == < 等...) 返回值是true / false 的纯布尔类型,不能像C++ 一样可以隐式转换为int类型
  • 在逻辑运算符中,&& 和 || 之类的与C++中的作用性质相同。但是 & 和 | 也能当作逻辑运算符 : & 和 | 如果表达式结果为boolean 时,也表示逻辑运算,但与 && || 相比,它们不支持短路求值.
  • 在位运算符中,java多了一个无符号右移 >>> :最右侧位不要了,最左侧补0
  • 以下是位运算的三点理解:
  1. 左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方.
  2. 右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方.
  3. 由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替.

3、逻辑控制

java中的逻辑控制语句也和C++非常的相似,以下依旧仅给出不同之处

  • 在Java所有逻辑控制语句中括号内必须是布尔表达式,不能像C++中一样还可以用int类型

  • 在switch语句中 括号内可以是以下类型的表达式:

    • 基本类型:byte、char、short、int,注意不能是long类型
    • 引用类型:String常量串、枚举类型
  • java中的范围for(e : 容器){} ,其中e为容器内的数据类型,其意义与C++中的范围for相似。

4、 输入输出

4.1、输出到控制台

java 复制代码
System.out.println(msg);            // 输出一个字符串, 带换行
System.out.print(msg);              // 输出一个字符串, 不带换行
System.out.printf(format, msg); // 格式化输出

4.2、从键盘输入

使用 Scanner 读取字符串/整数/浮点数

java 复制代码
import java.untl.Scanner; //需要导入util包
Scanner sc = new Scanner(System.in);
String name = sc,nextLine();
int age = sc.nextInt();
float salary = sc,nextFloat();
sc.close(); //注意:要记得调用关闭方法

5、方法

Java中的方法和C++中的函数是等同的,所以就不再阐述其概念和定义

注意事项:

  1. 修饰符:在没有清晰的理解Java中的类和对象时,目前我们要使用Java中的函数时直接用public static固定搭配
  2. 返回值类型:与C++中的规定相同,返回值类型必须要与返回的实体类型一致,如果没有返回值必须写成void。
  3. 方法命名:采用小驼峰命名(即名字的第二个单词开始的每个首字母大写)
  4. 参数列表: 要求与C++相同
  5. 方法体:方法内部要执行的语句
  6. 在java当中,方法必须写在类当中
  7. 在Java当中,方法不能进行嵌套定义
  8. 在Java当中,没有方法的声明这一说
  • 形参和实参的关系:

在java中形参和实参的关系也和C++相同,是两个不同的实体,所以就依然牵扯到了一个问题,方法中,传值调用的修改不能影响外部的实参 ,在java中我们将参数传入引用类型参数解决这个问题。

例题:交换两个整型变量:

  • 目前我们只知道String 和 数组 两种引用类型,选择用数组来解决这个问题
java 复制代码
	public class TestMethod{
		public static void main(String[] args){
		int a = 3;
		int b = 8;
		int[] arr = {a,b};
		swap(arr);
		System.out.println("arr[0] = "+ arr[0] + "arr[1] = " + arr[1]);
 }
 public static void swap(int[] arr){
 		int tmp = arr[0];
 		arr[0] = arr[1];
 		arr[1] = tmp;
 }
}

如果你现在有此疑问:为什么引用类型可以做到这样,那么你可以和C++中的指针进行对比理解

JAVA引用 C++指针
本质 作为指向某对象的地址副本 作为指向某对象的地址副本
进行地址运算 不支持 支持(例如 p++)
指向空值 可以为null 可以为nullptr
可以指向任意对象 不能,只能指向对象或数组 可以指向任何内存地址(所以会造成越界访问)
可以重新指向新对象 可以 可以
内存管理 自动垃圾回收 进行手动管理

接下来对上图进行解析:

  • 引用类型对象 是在 上开辟空间,其他类型对象上开辟空间
  • 传入参数后,在堆上又创建了一个副本,同样存着a,b的地址,然后指向的地址内部的对象 进行值的改变切实影响到外部

5、方法重载

与C++中的函数重载相同,不再过多赘述,以下给出构成重载的性质来方便复习:

  1. 方法名必须相同
  2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的顺序不同)
  3. 与返回值类型是否相同无关

6、方法签名

为什么方法重载可以实现,不会导致冲突,这就是由于方法签名的存在,它的本质底层和C++中的函数名修饰规则相似。

  • 方法签名 : 经过编译器优化后方法最终的名字 :方法路径名 +参数列表 + 返回值类型

编译后的具体名字有兴趣可以通过javac带的反汇编工具进行查看.class字节码

7、数组

虽然我们在C++中对数组的理解烂熟于心,但是在Java中对数组升级成了引用类型,所以其中的不同之处需要我们重新去理解

7.1数组的创建

T[] 数组名 = new T[N];

7.2数组的初始化

数组的初始化分为静态初始化动态初始化

  1. 动态初始化:在创建数组时,直接指定数组中元素的个数

    java 复制代码
    int[] arr = new int[10]]

2.静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定

java 复制代码
int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};
  • 静态初始化可以简写,省去后面的new T[]。
java 复制代码
int[] array1 = {0,1,2,3,4,5,6,7,8,9};
  • 静态和动态初始化也可以分为两步,但是就不能省去后面的new T[]。
java 复制代码
int[] array1;
array1 = new int[10];
  • 未初始化的数组元素将自动赋默认值

所有数字类型的默认值为 0

char 默认值为 /u0000

boolean 的默认值为 false

引用类型的默认值为 null

7.3数组的使用

java中数组的使用和C++中大差不差,遍历方式也相同,不详细进行展开

在Java中,想要取到数组的长度和C++中的方法不一样,用 对象.length取得

8、 jvm的内存分布

这里我们只介绍虚拟机栈,本地方法栈,堆,这三块空间

  • 虚拟机栈:就是我们常说的栈,局部的一些内容,包括方法的创建都会从虚拟机栈中申请空间
  • 本地方法栈:可以理解为,虚拟机本身使用的栈,底层由C++实现
  • 堆:所有引用类型都会储存在该区域

8.1、基本类型变量与引用类型变量的区别:

  • 基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
  • 而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。

8.2 认识null

  • 在Java中null表示 空引用

9、操纵数组

Java 提供了两种操作数组的基本方式:使用 Arrays 工具类调用数组对象的方法

9.1、区分Array的方法与数组对象方法

许多学过C++的朋友们学到这里容易产生很多的问题,可能会误以为Array是数组类型,但数组类型的创建不会new Array ,其实这里的Array是java中反射包里提供的一个工具类,该类并不能实例化出对象,只是提供了许多数组要使用的方法来供你调用。

接下来分别对这两种的方法进行介绍

9.2、数组对象常调用的方法

以下介绍的方法全部继承于Object类

方法签名 作用 返回值 说明
toString() 返回数组的字符串表示(哈希码) String 返回的并不是数组内容
equals(Object obj) 判断传入的另一个对象是否相等 boolean 这里判断的不是内容是否相等而是比较这两个是否都引用同一个对象
clone() 创建并返回数组的一个浅拷贝 Object 对一维基本类型数组是深拷贝;对引用类型数组是浅拷贝

9.3 Array常调用的方法

java.util.Arrays 是 Java 为数组提供的标准工具库。它的核心设计理念在于:将数组这一数据结构的常见操作(如排序、查找、复制等)都标准化、工具化,让开发者无需重复造轮子

以下的方法都是用Arrays. 的方式调用的

  1. asList(数组名) :将一个数组转换为一个 "固定大小" 的 List 视图(所以要用List接口接收)
  • 注意 它返回的是 Arrays 的内部类不支持 add() 和 remove() 操作 ,并且与源数组共享数据,可以调用 set(index, element) 修改已有元素
  • 如果你需要返回一个可变大小的 List,那么可以用new ArrayList<>(Arrays.asList(...)) 进行包装
java 复制代码
List<String> mutableList = new ArrayList<>(Arrays.asList("A", "B", "C"));
mutableList.add("D"); // 现在可以添加了
  1. sort(X[ ] a) :对整个数组进行升序排序。

  2. sort(X[ ] a, int fromIndex, int toIndex) (常用):对数组的指定范围进行排序。

  3. sort(T[ ] a, Comparator<? super T> c) (常用):根据指定的比较器规则对数组进行排序。

  4. binarySearch(X[] a, X key) (常用):使用二分查找算法在已排序的数组中 查找指定值,返回其索引

  5. equals(X[] a, X[] a2) (常用):比较两个一维数组 是否长度相等且对应元素也相等

  6. deepEquals(Object[] a1, Object[] a2) :比较两个多维数组 是否深度相等

8.compare(X[] a, X[] b) :按字典顺序 比较两个数组。它是 equals 方法的增强版,不仅能判断是否相等,还能比较大小关系

  1. mismatch(X[] a, X[] b) :查找并返回两个数组之间第一个不匹配元素的索引 ,如果完全相同则返回 -1

  2. fill(X[] a, X val) (常用):将一个数组的所有元素都填充为同一个指定值

  3. fill(X[] a, int fromIndex, int toIndex, X val) (常用):将数组指定范围内 的元素填充为同一个值

  4. copyOf(X[] original, int newLength) (常用):复制数组 ,并根据 newLength 进行截断或用默认值填充 ,来实现数组的扩容或缩容

  5. copyOfRange(X[] original, int from, int to) (常用):复制数组的指定范围(from 索引包含,to 索引不包含)

  6. toString(X[] a) (常用):返回一维数组 内容的字符串表示,是打印数组的首选方法

  7. deepToString(Object[] a) :返回多维数组内容的字符串表示。

  8. reverse.():返回该数组的反转结果

9.4、二维数组

Java中二维数组本质上就是元素为一维数组的一维数组

语法:

数组类型[][] 数组名称 = new 数据类型 [行数][列数]{初始化数据}

相关推荐
zjun10011 小时前
QT:语言翻译
开发语言·qt
千寻girling1 小时前
机器学习 | 逻辑回归 | 尚硅谷学习
java·人工智能·python·学习·算法·机器学习·逻辑回归
Javatutouhouduan2 小时前
阿里2026最新Java面试核心讲(终极版)
java·java面试·java并发·后端开发·java程序员·java八股文·java性能优化
Shadow(⊙o⊙)2 小时前
C++常见错误解析2.0
开发语言·数据结构·c++·后端·学习·算法
京师20万禁军教头2 小时前
34面向对象(中级)-断点调试
java
谢谢 啊sir2 小时前
L2-057 姥姥改作业 - java
java·开发语言
将心ONE2 小时前
pathlib Path函数的使用
java·linux·前端
l1t2 小时前
duckdb excel插件和rusty_sheet插件在python中的不同表现
开发语言·python·excel
Royzst2 小时前
常用APL
java