2023.2.13(第一天)
Java是如何实现跨平台的?
Java是通过JVM(Java虚拟机)实现跨平台的。
JVM可以理解成一个软件,不同的平台有不同的版本。我们编写的Java代码,编译后会生成.class 文件(字节码文件)。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码,通过JVM翻译成机器码之后才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。
只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。
因此,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的翻译才能执行。
面向对象和面向过程的区别?
面向对象和面向过程是一种软件开发思想。
-
面向过程就是分析出解决问题所需要的步骤,然后用函数按这些步骤实现,使用的时候依次调用就可以了。
-
面向对象是把构成问题事务分解成各个对象,分别设计这些对象,然后将他们组装成有完整功能的系统。面向过程只用函数实现,面向对象是用类实现各个功能模块。
Java 与 C++ 的区别
- Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 兼容 C ,不但支持面向对象也支持面向过程。
- Java 通过虚拟机从而实现跨平台特性, C++ 依赖于特定的平台。
- Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。
- Java 支持自动垃圾回收,而 C++ 需要手动回收。
- Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。
JDK/JRE/JVM三者的关系
JVM
英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。Java 能够跨平台运行的核心在于 JVM 。
所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。也就是说class文件并不直接与机器的操作系统交互,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
针对不同的系统有不同的 jvm 实现,有 Linux 版本的 jvm 实现,也有Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。这就是Java能够跨平台,实现一次编写,多处运行的原因所在。
JRE
英文名称(Java Runtime Environment),就是Java 运行时环境。我们编写的Java程序必须要在JRE才能运行。它主要包含两个部分,JVM 和 Java 核心类库。
JRE是Java的运行环境,并不是一个开发环境,所以没有包含任何开发工具,如编译器和调试器等。
如果你只是想运行Java程序,而不是开发Java程序的话,那么你只需要安装JRE即可。
JDK
英文名称(Java Development Kit),就是 Java 开发工具包。JDK目录下有个JRE,也就是JDK中已经集成了 JRE,不用单独安装JRE。
他们三者的关系
JRE = JVM + Java 核心类库
JDK = JRE + Java工具 + 编译器 + 调试器
面向对象有哪些特性?
面向对象三大特性:封装,继承,多态,
1、封装就是将类的信息隐藏在类内部,不允许外部程序直接访问,而是通过该类的方法实现对隐藏信息的操作和访问。 良好的封装能够减少耦合。
2、继承是从已有的类中派生出新的类,新的类继承父类的属性和行为,并能扩展新的能力,大大增加程序的重用性和易维护性。在Java中是单继承的,也就是说一个子类只有一个父类。
3、多态是同一个行为具有多个不同表现形式的能力。在不修改程序代码的情况下改变程序运行时绑定的代码。实现多态的三要素:继承、重写、父类引用指向子类对象。
- 静态多态性:通过重载实现,相同的方法有不同的參数列表,可以根据参数的不同,做出不同的处理。
- 动态多态性:在子类中重写父类的方法。运行期间判断所引用对象的实际类型,根据其实际类型调用相应的方法。
面向对象编程的六大原则?
- 对象单一职责:我们设计创建的对象,必须职责明确,比如商品类,里面相关的属性和方法都必须跟商品相关,不能出现订单等不相关的内容。这里的类可以是模块、类库、程序集,而不单单指类。
- 里式替换原则:子类能够完全替代父类,反之则不行。通常用于实现接口时运用。因为子类能够完全替代基(父)类,那么这样父类就拥有很多子类,在后续的程序扩展中就很容易进行扩展,程序完全不需要进行修改即可进行扩展。比如IA的实现为A,因为项目需求变更,现在需要新的实现,直接在容器注入处更换接口即可.
- 迪米特法则,也叫最小原则,或者说最小耦合。通常在设计程序或开发程序的时候,尽量要高内聚,低耦合。当两个类进行交互的时候,会产生依赖。而迪米特法则就是建议这种依赖越少越好。就像构造函数注入父类对象时一样,当需要依赖某个对象时,并不在意其内部是怎么实现的,而是在容器中注入相应的实现,既符合里式替换原则,又起到了解耦的作用。
- 开闭原则:开放扩展,封闭修改。当项目需求发生变更时,要尽可能的不去对原有的代码进行修改,而在原有的基础上进行扩展。
- 依赖倒置原则:高层模块不应该直接依赖于底层模块的具体实现,而应该依赖于底层的抽象。接口和抽象类不应该依赖于实现类,而实现类依赖接口或抽象类。
- 接口隔离原则:一个对象和另外一个对象交互的过程中,依赖的内容最小。也就是说在接口设计的时候,在遵循对象单一职责的情况下,尽量减少接口的内容。
什么是值传递和引用传递?
- 值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。
- 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身,两者指向同一片内存空间。所以对引用对象进行操作会同时改变原对象。
java中不存在引用传递,只有值传递。即不存在变量a指向变量b,变量b指向对象的这种情况。
自动装箱和拆箱
Java中基础数据类型与它们对应的包装类见下表:
装箱:将基础类型转化为包装类型。
拆箱:将包装类型转化为基础类型。
当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:
- 赋值操作(装箱或拆箱)
- 进行加减乘除混合运算 (拆箱)
- 进行>,<,==比较运算(拆箱)
- 调用equals进行比较(装箱)
- ArrayList、HashMap等集合类添加基础类型数据时(装箱)
String, StringBuffer 和 StringBuilder区别
1. 可变性
- String 不可变
- StringBuffer 和 StringBuilder 可变
2. 线程安全
- String 不可变,因此是线程安全的
- StringBuilder 不是线程安全的
- StringBuffer 是线程安全的,内部使用 synchronized 进行同步