java学习篇(一)—— CPP和Java的区别之基础概念
一些感想
写在开头,如果你是一个坚定选择工作的研究生,在CPP和Java之间反复跳转,那么有以下几种情况,建议你选CPP:
- 对CPP有强大的兴趣,且组内有成熟的方向,例如:高性能计算、音频开发等方向,可以选择。
- 仅仅想找一份工作,不要跟自己过不去,Java很好,尤其是后端。
博主是在模型部署里做了一年,但是由于确实不感兴趣,荒废时间后发现自己的工作上毫无优势,最终无奈学习Java的。
Java有很明确的学习路线:Java基础--->JDBC + 数据库--->Java web---> spring--->SpringCloud + Redis + 中间件巴拉巴拉。
由于博主之前在CPP上有一些学习经验,但是网上的学习路线都是针对于零基础的,这样无疑会增加学习成本,所以想要记录一下整个学习过程,给同样苦苦挣扎的人一些帮助。
在写完这个博客之后,个人认为以下几个方面可以帮助你快速了解Java和cpp的不同:JVM、接口、引用变量类型、Object类、接口与泛型。这几个是最能体现Java面向对象编程思想的。
程序运行的区别
C++的代码想要运行就需要编译,编译过程包括:预处理、编译、汇编、连接。针对不同的操作系统和CPU架构,需要特定的编译器,例如x86和arm的指令不同,那么需要的编译工具链也不同。而Java程序的.java
文件通过javac
编译成.class
字节码文件(不是机器码),字节码由 Java 虚拟机JVM解释或JIT编译为本地机器码运行,不同操作系统和硬件平台,只要安装了对应的 JVM,就能运行这些.class
或.jar
文件。综上,Java在可移植性上具有强大的优势。
因此,Java也被叫做解释型语言,Java源代码被编译成字节码后,需要解释这些字节码才能在计算机上运行。
JVM带来的优势
cpp想要实现什么功能,都是以调用的形式,例如调用操作系统Socket的接口、操作系统thread的接口、调用自己写的接口,且由于依赖于底层的框架和操作系统,因此cpp针对一些功能实现没有相对应的库,例如实现webserver,就需要自己实现http协议、路由分发、多线程和数据库等等,而这些在Java里只需要对应的模块就可以。根本原因是,Java的可移植性更强,使得它可以做一套统一的接口供不同的平台调用。
面向过程与面向对象
这是两个有点抽象的概念,但观察.cpp和.java的程序,一个显著的差异就是main()
函数的位置,在.java程序里,main()
只能定义在类里,或者说,所有代码都必须属于类。回忆一下cpp代码,.h
是头文件,定义类,成员函数,成员变量等,.cpp
是我们想要实现的功能。功能被拆解成了无数个子任务,最终在main()
里顺序执行,这就是面向过程。Java 是“纯面向对象语言”(除了基本类型),强调“一切皆类”,所以main
也必须属于某个类,即使它是程序入口点。Java将所有的函数定义为了方法(Method),方法的调用必须通过对象或者类来实现,而CPP中则可以通过直接调用。Java的接口机制使得它能够很好的对对象进行封装,Object
类使得JVM的任何对象都可以被方法统一调用。
Java代码的执行方式包括两种,分别是:
执行方式 | 描述 |
---|---|
解释执行 | 最初由 JVM 中的 解释器 一条条解释字节码指令执行(速度较慢) |
即时编译(JIT, Just-In-Time Compilation) | 对“热点代码”(重复调用的方法)进行 动态编译成本地机器码,大幅提升运行速度 |
正是这种执行方式,使得Java可以运行时多态。
Q:一个有main
函数的类实例化了另一个有main
函数的类,那么调用谁的main
?
在.cpp里,一个main
函数意味着一个可执行文件,不可能存在可执行文件调用另一个可执行文件,只能依赖操作系统再开一个进程。但是在Java里,却实现了这个,Java 允许多个类都有 public static void main(String[] args) 方法,但是程序执行时只会从你运行的那个类的main
方法开始执行,其它的main不会自动调用。目前能想到的优势,大概只有调试比较方便,毕竟在一个封装好的类里加main
很奇怪。
变量类型
C++的数据类型包括:基本类型、自定义类型、指针类型、引用类型。你可以指定变量在堆上还是栈上,不使用new
的话,默认对象在栈上,而在堆上申请的内存需要手动释放。
在Java里,包括两种变量类型:基本类型和引用类型,除了int
这种基本类型外的类、接口、数组、自定义对象(包括 String、List、自定义类等)全是引用类型,只有你new
出一个对象才会在堆上分配实际空间。
我们使用代码来说明两者的区别:
Myclass a;
Myclass b = a;
在C++里,上述代码会在栈区创建两个实例,sizeof(a)==sizeof(b)==sizeof(Myclass)
,也就是说,栈上的就是对象本身,等号进行的是赋值操作(堆操作符=的重写)。但是当Java执行这个语句之后,sizeof(a)==sizeof(b)==4/8字节
,可以认为,这只是两个指针,由于没有指向具体的对象实例,所以是空。这里可以看出,Java的引用可以为空,C++不可以。
再看一个代码:
Myclass a = new Myclass();
Myclass *a = new Myclass();
上面的语句是Java在堆上实例化对象,下面语句是C++在堆上实例化对象,a
都是储存在栈区的变量,指向堆上的实例。
线程调度的区别?
cpp的线程管理依赖于操作系统的API,而Java由于有自己的虚拟机,所以在操作系统的线程管理上可以再进行一次封装,所以Java通过线程池框架来对线程进行管理。CPP的优势在移动端对性能敏感的业务里更能体现,比如线程绑定核心,安卓移动应用开发使用的是JNI调用底层的C/C++接口。Java线程生命周期有六个状态,在操作系统的线程状态上对等待态进行了划分,分为:阻塞,等待,定时等待。
网络编程
我没有网络编程开发经验。。。。
维度 | Java网络编程 | C++网络编程 |
---|---|---|
易用性 | 高(内置库+面向对象封装) | 低(依赖系统API或第三方库) |
跨平台 | 统一平台(JVM) | 需适配多平台 |
性能 | 较高 | 极高 |
内存安全 | 自动管理 | 手动管理,需谨慎 |
异步支持 | NIO、AIO | Boost.Asio等异步库 |
典型应用 | 企业级应用、服务端 | 高性能服务器、底层系统 |
接口编程 + 多态
cpp的多态通过虚函数实现的,子类重写父类的虚函数来实现多态。而对于Java而言,实现多态有两个机制: 1. 重写父类的成员函数,不需要声明为虚函数或者接口,直接子类前面+@override
即可。 2. 直接声明一个接口,而实现它的类必须重写接口。这里需要强调的是,这个接口不是父类,这种实现是重写,而不是继承。接口可以继承,一个接口可以继承另一个接口
父类中的任何函数都可以重写吗?
有限制,以下几种方法不可以重写:
private
方法:子类无法访问父类的private方法,自然也无法重写,如果你在子类中写了同名方法,其实是一个新的方法,不是重写。final
方法:被final
修饰的方法不能被重写,编译器会报错。static
方法:静态方法属于类,不属于对象,不能被重写,但可以在子类中定义一个同名的静态方法(这叫“隐藏”,不是重写)。
注意!由于Java的垃圾回收机制,所以不需要析构函数!
模板与泛型
这里体现了JVM存在的优势,cpp编译器编译出可执行文件之后,一切按照可执行文件来运行,而Java则是在编译时擦除类型信息,在运行时由JVM根据对象的类型指针来知道这个对象是什么类型的,进行类型强制转化。而泛型擦除的安全,又编译器负责检查,JVM知道当前代码一定是类型安全的,只需要根据你传入的对象类型,判断实际的类型就可以了。
泛型
Java 编译器在编译时使用泛型进行类型检查和类型推导,但在编译完成后,所有的泛型类型信息都会被“擦除”。例如:
List<String> list = new ArrayList<>();
list.add("hello");
// 编译后的字节码中其实是:
List list = new ArrayList();
list.add("hello"); // 没有泛型类型
泛型类型参数会被擦除为其上界(默认为 Object),如果你写了 ,擦除后就是Number
,所有泛型方法、类只会生成一份.class
文件。
JVM并不需要知道泛型的类型,它只当作是Object或擦除后的上界类型来处理,依靠的是多态机制(方法分发)和强制类型转换。
模板
C++ 在模板使用时,每用一个类型实例化模板,就生成一个新的代码版本。按需实例化:遇到新类型就生成新函数/类,每个模板参数类型对应一个完整实现,生成的是普通函数/类,与泛型无区别。可以认为是,编译器帮你做了重复性的代码工作,但是在编译时,他们就是不同的类型。
java学习篇(一)—— CPP和Java的区别之基础概念的更多相关文章
- Java 学习(17): Java 泛型
Java 泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说将 ...
- Java 学习(18):Java 序列化& 网络编程& 发送邮件
--Java 序列化 -- 网络编程 -- 发送邮件 Java 序列化 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信 ...
- Java 学习(19):Java 多线程编程
Java 多线程编程 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...
- Java 学习(20):Java Applet 基础 & Java 文档注释
-- Java Applet 基础 -- Java 文档注释 Java Applet 基础 Applet 是一种 Java 程序.它一般运行在支持 Java 的 Web 浏览器内.因为它有完整的 Ja ...
- Java 学习(21):Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...
- Java 学习(22):Java MySQL 连接
Java MySQL 连接 本章节我们为大家介绍 Java 如何使用 使用 JDBC 连接 MySQL 数据库. Java 连接 MySQL 需要驱动包,最新版下载地址为:http://dev.mys ...
- 最新java学习路线:含阶段性java视频教程完整版
最新java学习路线:带阶段性java视频教程版本 第一阶段:Java基础 学习目标: 掌握基本语法.面向对象.常用类.正则.集合.Io流.多线程.Nio.网络编程.JDK新特性.函数式编程 知识点细 ...
- Java 学习(1): windows java 运行& 环境配置
Java 文件的运行 如下,创建了一个 名为"HelloWorld.java" 的 Java 文件: public class HelloWorld { public static ...
- Java 学习(2):java 基础概念
Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 基础语法: 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.以 ...
- Java 学习(3):java 对象和类
目录: --- 对象 --- 类 --- 源文件的声明规则 --- Java 包 对象: 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种: ...
随机推荐
- 接口介绍以及定义和使用--java进阶day02
1.接口介绍 日常生活中有很多接口,比如手机数据线的接口和手机充电器的接口 我们转换视角,站在设计者的角度思考接口,接口体现出规则,手机的接口大小和数据线的接口大小必须一致,各种接口的大小都要一致,都 ...
- 【Java】Java提取${}占位符并组装对应值
目录 Java提取${}占位符并组装对应值 零.起因 壹.想法 贰.实现 叁.总结 肆.参考文档 Java提取${}占位符并组装对应值 实现了一个${}装配工~ 零.起因 最近写个JavaWeb项目, ...
- TimeSpan 的 Milliseconds 和 TotalMilliseconds 有啥区别?
有小伙伴问到 TimeSpan的 Milliseconds和TotalMilliseconds有啥区别啊? 我用TimeSpan.FromSeconds(3600).Milliseconds就获取到是 ...
- 《机器人SLAM导航核心技术与实战》第1季:第8章_激光SLAM系统
<机器人SLAM导航核心技术与实战>第1季:第8章_激光SLAM系统 视频讲解 [第1季]8.第8章_激光SLAM系统-视频讲解 [第1季]8.1.第8章_激光SLAM系统_Gmappin ...
- 虚拟机为什么ping不通主机
在虚拟机里各种操作都正常.就是ping不通主机.为什么? NAT模式下(网络地址转换模式),虚拟机后网络适配器就会出现VMnet8网卡: 把VMnet8的ip4设定成你主机同段IP.这个VMnet8地 ...
- .NET多线程编程之CountdownEvent使用
简单来说,使用这个类可以让主线程等待子线程都完成任务之后才执行任务 1 static void Main(string[] args) 2 { 3 ///子任务的数量 4 CountdownEvent ...
- HTB打靶记录-EscapeTwo
信息收集 nmap -sV -sC -O 10.10.11.51 Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-05 14:52 CST Sta ...
- 从DeepSeek看算法备案&大模型备案
一.deepseek的备案情况 (一)算法备案情况 在算法备案系统网站上,北京深度求索人工智能基础技术研究有限公司和杭州深度求索人工智能基础技术研究有限公司分别进行了两个算法备案.从公司名称来看,正如 ...
- lua三色标记的读写屏障理解
起因是已经被标记为黑色的对象无法进行再次遍历,然而黑色对象发生了引用变化:断开了引用或者引用了别的对象,会导致多标(不再被黑色对象引用的对象未能回收),漏标(黑色对象的新引用未能遍历标记)
- liunx git 免密码登录
vscode远程git或在linux环境使用git时,每次clone都要输入帐号密码,很不方便,可以使用下面一行命令,系统会记录你输入的下一次帐号密码.(明文记录,注意规避风险) # 执行 g ...