Java基础知识(一)

一、 JVM 虚拟机

JVM是运行Java字节码的虚拟机。而基于不同平台,相同的Java字节码,执行之后会产生相同的结果,这也是实现跨平台的关键。

JVM 并不是特有的,只要满足JVM规范,每个公司或组织或者个人,都可以开发自己专属的JVM。

二、JDK 和 JRE

JDK是 Java Development Kit 的缩写,是功能齐全的 SDK。它包含 JRE 所拥有一切,还包括: javac、javadoc、jdb。它能够创建程序、编译程序。

JRE是Java运行时环境。用来运行已编译好的Java程序,包括Java虚拟机、Java类库、java命令和其他的一些基础构建。但是它不能用于创建新程序。如果只是要运行Java程序的话,则只需要安装JRE就可以了,如果需要支持Java编程工作的话,则需要安装JDK了。

三、什么是字节码、采用字节码的好处是什么

在Java中,字节码是可以被JVM理解的代码 (即扩展名为 .class的文件)。它跟特定的设备无关,只面向于虚拟机JVM。Java语言通过字节码的方式,在一定程度上解决了那些传统语言执行效率低的问题,同时又保留了可移植的特性,为此Java程序的执行效率还算是比较高的了,并且实现一次编译跨平台执行。

Java程序从源码到运行的过程如下:

Java基础知识(一)_第1张图片

我们需要重点关注一下 .class -> 机器码 这一步。首先是 JVM 类加载器加载字节码文件 .class。然后通过解释器逐步解释执行,这种方式执行速度比较慢。为此后来引入了 JIT 编译器(运行时编译)。 当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。

四、为什么说 Java 语言 "编译与解释并存"?

高级编程语言按照程序的执行方式分为:

  • 编译型 :编译型语言 会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言的执行速度比较快,开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
  • 解释型 :解释型语言会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。

Java基础知识(一)_第2张图片

 为什么说 Java语言是 "编译与解释并存"的呢?

这是因为 Java 语言既具有编译型语言的特征,也具有解释型语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行。

五、基础语法部分

1. 字符常量和字符串常量的区别

  • 形式 : 字符常量是单引号括起的一个字符,字符串常量是双引号括起的 0 个或若干个字符。
  • 含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算;   字符串常量代表一个地址值(该字符串在内存中存放位置)。
  • 占内存大小 : 字符常量只占 2 个字节; 字符串常量占若干个字节。

举例:

# char 是基本数据类型,一个char 只能保存一个 Unicode 字符:

char c1 = 'A';

char c2 = '中';

# Java 在内存中,总是使用 Unicode 表示字符,所以一个英文字符和一个中文字符,都只占用两个字节。如果要显示一个字符的 Unicode 编码,只需要将 char 类型直接赋值给 int 类型即可:

int  n1 = 'A';    //字符 A 的Unicode编码是 65

int n2 = '中';    // 汉字 “中” 的Unicode 编码是 20013

# 还可以直接用转义字符 \u + Unicode 编码来表示一个字符:

char c3 = ‘\u0041’;    // 'A', 因为十六进制0041 = 十进制65

char c4 = '\u4e2d';    // '中', 因为十六进制4e2d = 十进制 20013

2. 静态方法为什么不能调用非静态成员?

这个需要结合 JVM 的相关知识,主要原因如下:

  1. 静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。
  2. 在类的非静态成员不存在的时候静态成员就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。

3. 静态方法和实例方法有何不同?

3.1 调用方式上的区别

调用一个静态方法的可以是  类.方法名,也可以是 对象.方法名,一般我们使用  类.方法名

调用一个非静态方法只能是 对象.方法名。

3.2 访问类成员是否存在限制?

静态方法里在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),不允许访问实例成员(即实例成员变量和实例方法),而实例方法不存在这个限制。

4. 重载和重写的区别

重载   就是名字相同但参数不同的几个方法,能够根据输入参数的不同,做出不同的处理。典型的应用场景是 构造方法的重载。

重写   就是当子类继承父类中的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法。

4.1 重载

发生在同一个类中 (或者父类和子类之间),重载的方法名必须相同,参数类型、个数、顺序不同,返回值和访问修饰符也可以不同。

综上:重载就是同一个类中多个同名方法根据不同的传参来执行不同的逻辑处理。

4.2 重写

重写是发生在运行期间的,是子类对父类中允许访问的方法的实现过程 进行重新实现。

  1. 方法名、参数列表必须相同,子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
  2. 如果父类方法访问修饰符为  private / final / static  则子类就不能重写该方法,但是被 static 修饰的方法能够被再次声明。
  3. 构造方法无法被重写

综上:重写就是子类对父类方法的重新改造,外部样子不能改变,内部逻辑可以改变。

5. 8中基本数据类型

  • 6 种数字类型:
    • 4 种整数型:byteshortintlong
    • 2 种浮点型:floatdouble
  • 1 种字符类型:char
  • 1 种布尔型:boolean

这 8 种基本数据类型的默认值以及所占空间的大小如下:

Java基础知识(一)_第3张图片

这八种基本类型都有对应的包装类分别为:ByteShortIntegerLongFloatDoubleCharacterBoolean 

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

  • 包装类型的默认值是 null ,而基本类型的默认值不是 null
  • 包装类型可用于泛型,基本类型不可以。
  • 基本类型的局部变量存放在 JVM 栈中的局部变量表中,基本类型的成员变量(未被 static 修饰 )存放在 JVM 堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于 JVM 堆中
  • 相比于对象类型, 基本数据类型占用的空间非常小。

注意基本数据类型存放在栈中是一个常见的误区! 基本数据类型的成员变量如果没有被 static 修饰的话(不建议这么使用,应该要使用基本数据类型对应的包装类型),就存放在堆中。

7. 包装类型的缓存机制

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

ByteShortIntegerLong 这 4 种包装类型默认创建了数值 [-128,127] 的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False

8. 自动装箱与拆箱原理

8.1 什么是自动拆装箱

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

Integer i = 10;  //装箱

int n = i;           //拆箱

查看生成的字节码可知:

  • Integer i = 10 等价于 Integer i = Integer.valueOf(10)
  • int n = i 等价于 int n = i.intValue();

你可能感兴趣的:(Android,Java,java,开发语言)