day_01——Java基础

基础概念与常识


Java 语言的几个特点

  1. 简单易学 (😀)
  2. 面向对象 (封装、继承、多态)
  3. 平台无关性 (Java 虚拟机实现平台无关性)

    “Write Once,Run Anywhere !!!(一次编写,随处运行)”

  4. 高效性(通过 Just In Time 即时编译等技术的优化,Java 语言的运行效率比解释性语言高)
  5. 编译与解释并存
  6. … …

Java SE vs Java EE

Java SE 是 Java 的基础版本,Java EE 是 Java 的高级版本。另外还有 Java ME 用于开发嵌入式,现在已经用不上了

JDK vs JRE vs JVM

JDK(Java Development Kit) 是提供给开发者使用,能够创建和编译 Java 程序的开发套件。它包含了 JRE 、编译 java 源码的编译器 javac、jdb 调试器、javadoc 文档注释工具等等

JRE(Java Runtime Environment) 是 Java 运行时环境。它是运行已编译的 Java 程序所需的所有内容的集合,主要包括 Java 虚拟机(JVM)和 Java核心类库。

JVM 是运行 Java 字节码文件的虚拟机,在不同的操作系统中使用相同的字节码文件通过 JVM 的解释都会得到相同的结果。是实现"Write Once,Run Anywhere !!!(一次编写,随处运行)"的关键所在.

什么是字节码,采用字节码的好处是什么?

在 Java 中,JVM 可以理解的代码就叫做字节码(即拓展名为.class的文件),字节码通过对 Java 源码进行编译得来。字节码只面向虚拟机,并不针对某一特定的机器,因此 Java 程序无需重新编译便可通过 JVM 在不同的操作系统的计算机上执行。

需要注意的是 .class -> 机器码这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度较慢,且有些方法和代码块是经常需要被调用的,所以后面引进了 JIT (Just In Time Compilation)即时编译器,而 JIT 属于运行时编译器。当 JIT 编译器完成第一次编译之后,会将字节码对应的机器码保存下来,下次可以直接使用。这就提高了 Java 程序的执行效率,也解释了为什么 Java 语言“编译与解释”共存?

为什么说 Java 语言“编译与解释”共存?

我们将高级语言按照程序的执行方式可分两种:

  • 编译型:编译型语言会通过编译器一次性翻译成计算机可执行的机器码,一般情况下,编译型语言的执行速度比较快,开发效率比较低。常见的语言有:C、C++ 等等。
  • 解释型:解释型语言会通过解释器一句一句的解释成机器码后再执行,解释型语言执行速度较慢,但开发效率比较高。常见的语言有:Python、JavaScript 等等。

Java 语言既具有解释型语言的特征,又具有编译型语言的特征。这是因为 Java 程序需要先编译成.class字节码文件,这种字节码必须由 JVM 中的 Java 解释器来解释执行。

AOT有什么优点?为什么不全部使用 AOT 呢?

JDK9 进入了性的编译模式 AOT (Ahead of Time Compilation) 提前编译。和 JIT 不同的是,这种编译模式会在程序执行前就将其编译成机器码,属于静态编译(C、C++等语言就是静态编译)。AOT避免了 JIT 预热等方面的开销,可以提高 Java 程序的启动速度,且 AOT 还能减少内存消耗和增强 Java 程序的安全性。
AOT 的优势在于启动速度、内存占用和打包体积。JIT 的优势在于具备更高的极限处理能力,可以降低请求的最大延迟。

既然 AOT 这么多有点,为什么不全部使用 AOT 呢?
因为 AOT 是静态编译,所以 AOT 编译无法支持 Java 的一些动态特性,如反射、动态代理、动态加载等。然而,很多框架(如 Spring)都用到了这些特性,如果只使用 AOT 编译,那就无法使用这些框架了。

Java 和 C++ 的区别?

Java 和 C++ 都是面向对象的语言,都支持封装继承多态,不同:

  • Java 不提供指针,程序内存更安全,但也缺失了内存优化的可能性。
  • Java 的类是单继承的,C++ 支持多继承;但是 Java 的接口支持多继承
  • Java 具有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存
  • C++ 支持方法和操作符的重载,但是 Java 只支持方法重载
  • … …

基本语法


Java 关键字与标识符

标识符就是类、方法、变量 、程序的名字,关键字就是已经被赋予特殊含义的标识符。
注意:虽然true,false,null看起来像关键字但实际上他们是字面值,同时不可做为标识符使用

移位运算符

<<>>都是算数运算符,符号位不参与移位,相当于乘以2和除以2.
>>>是逻辑右移运算符,符号位也参与移位,
移位运算符实际上支持的只有 intlong ,编译器在对 byteshortchar类型移位前,都会将其转化为int类型再操作。
由于floatdouble在二进制中比较特殊,以此不支持移位操作

基本数据类型


基本数据类型

byte、short、int、long、float、double、char、boolean
注意:Java 里使用long类型的数据一定要在数值后面加L,否则将作为int解析。

基本类型和包装类型的区别?

  • 用途:在定义局部变量和常量时,用基本类型。在比如方法参数、对象属性中使用包装类型。且包装类型可用于泛型,基本类型不可以用于泛型。
  • 存储方式:基本类型的局部变量存储在虚拟机的栈中,随方法运行结束而消失,基本类型的成员变量(未被 static 修饰的,属于对象),放在虚拟机的堆中;而包装类型属于对象类型,基本所有的对象实例都存在堆中,
  • 占用空间:相比与包装类型,基本类型占用的空间往往非常小。
  • 默认值:包装类默认值为null,而基本类型都有默认值且不为null
  • 比较方式:包装类型用 == 比较的是地址 equals 比较的是值,基本类型 == 比较的是值。

注意:**基本数据类型存放在栈中是一个常见的误区!**基本数据类型存储位置取决于它们的作用域和声明方式。如果是局部变量,存在在栈中;如果是成员变量。则存放在堆中。

包装类型的缓存机制

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。

Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False
在此区间的相同值的地址一致。

自动装箱与拆箱

  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;

注意:如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。

为什么浮点数运算的时候会有精度丢失的风险?

跟计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的,而计算机在表示一个数字时,宽度是有限的,无限循环的的小数存储在计算机时,就会被截断,所以会导致浮点数精度丢失。

如何解决浮点数运算的精度丢失问题

BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 BigDecimal 来做的。

超过 long 整型的数据应该如何表示

BigInteger 内部使用 int[] 数组来存储任意大小的整形数据。

相对于常规整数类型的运算来说,BigInteger 运算的效率会相对较低。

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值