JDK、双亲委托机制、命名、基本类型、数组

一些之前不太了解的东西

Day1

1、Java程序是运行在Java虚拟机上的,一次编译,处处运行。
2、现行的默认虚拟机是HotSpot,常用的三大虚拟机包括、Java历史、Java版本(社区版和商业版)、Java维护——TODO
3、JVM Java虚拟机 Java运行依赖的环境
JRE Java运行环境 包含JVM和运行包
JDK Java开发库 包含JRE和开发包
JDK > JRE > JVM
4、Java文件有且只有一个public class,且与文件名相同。在此之外有几个类就有几个编译的.class文件。
5、通过 javac -encoding utf-8 设定编译产生字节码的编码格式。
6、jar包是.class字节码文件的集合压缩文件
7、Java程序运行流程:

  • 编译阶段:Java源码——Javac编译——>.class字节码文件
  • 运行阶段:.class字节码——加载到内存中——在JVM中

    • JVM:类加载器加载类——字节码校验——解释器(JIT)转成二进制代码——CPU运行
      • (加载——校验——解释——运行)
    • 热点代码:HotSpot能够将经常执行的热点代码直接在编译阶段解释成二进制代码供机器直接运行,效率高

      Day2

      1、System类是在Java运行环境的rt.jar中的,并在JVM运行时首先加载,之后才加载用户自定类
  • 这与“双亲委托机制”有关

2、全限定类名——包名.子包名.类名——是JVM加载时使用的类名
3、与Java有关的命令:

  1. #命令编译带包名的Java程序:
  2. javac -d ../bin Hello.java
  3. #-d是为指定路径自动创建包(假设当前在/src/文件夹中)
  4. #命令运行带包名的Java字节码:
  5. java -cp ../bin Hello #-cp是临时指定字节码的包的路径(classPath)
  6. #命令打包:
  7. jar -cvf ./a.jar ../bin
  8. #c是创建文件,v是显示打包过程,f是指定文件名
  9. #整个过程会将bin目录打包放到当前目录

4、类加载器:Java虚拟机带有三个类加载器,负责把不同类型的Java程序加载到内存中

  • 启动类加载器(BCL):加载\jre\lib和\jre\classes下的jar包,如rt.jar,是JVM启动的必须,C++语言编写
  • 拓展类加载器(ECL):加载\jre\lib\ext下的jar包,Java编写
  • 应用类加载器(ACL):加载CLASSPATH下的用户需要加载的.class文件
  • 以上三个按双亲委托机制进行调用和加载:

    • 双亲委托机制:加载.class文件->ACL是否加载过->ECL是否加载过->BCL是否加载过 ->BCL能否加载->ECL能否加载->ACL能否加载——以上判断若为“是”,则加载;判断依据是路径下有无对应的程序

      Day3

      1、注释也是有可能会被编译的,当注释中存在\u转义的换行符时(\u000d),后面的代码就会在编译时换行,作为代码执行
      2、标识符推荐命名规则:
  • 包名:全字母小写,使用.连接(name.space)

  • 类:首字母大写,大驼峰式(NameSpace)
  • 方法:首字母小写,小驼峰式(nameSpace)
  • 变量:首字母小写,使用_连接(name_space);或小驼峰式
  • 常量:全字母大写,使用_连接(NAME_SPACE)

3、原码、反码、补码:对于正有符号数,三码都一样;对于负有符号数,反码为原码“符号位不变,余位取反”,补码为反码“+1”
4、对于一个整形常量,默认是int类型;对于一个浮点型常量,默认是double类型;高范围常量赋值给低范围变量若超范围会报错:

  1. byte a = 1; // 不报错
  2. byte i = 1000; // 1000是int类型,超过byte范围(-128~127),报错
  3. byte i = 100+a; // a的范围不确定,报错
  4. a = 127; a += 1; a++; // 不报错,+=的结果是-128
  5. int b = a; // 不报错
  6. float i = 1.5; // 报错,1.5为double类型
  7. float i = 1.5f; // 不报错

高范围变量向低范围变量赋值会报错:

  1. int a = 100;
  2. byte i = a + 1; // 报错
  3. byte i = (byte)a; // 前24位被截断,不报错

5、一个数异或同一个数两次还是同一个数。可以使用异或交换两个变量:

  1. a = 1; b = 2;
  2. a = a ^ b; // 即a = 1 ^ 2
  3. b = a ^ b; // 即b = 1 ^ 2 ^ 2 = 1
  4. a = a ^ b; // 即a = 1 ^ 1 ^ 2 = 2

6、逻辑运算符和位的逻辑运算符有些不一样:逻辑运算符(&&、||)是短路运算;而位的逻辑运算符(&、|)是非短路运算。

Day4

1、对于switch语句,在JDK1.7以前,只能够判断整数、char和boolean类型;在JDK1.7中增加了字符串类型和枚举类型。其他的类型(浮点数)和对象,则不能判断。
2、变量:根据作用范围,分为局部变量和成员变量。根据数据类型,分为基本类型和引用类型。

  • 局部变量:定义在方法、循环体、if-else等大括号内的变量。
  • 成员变量:可以理解为全局变量,定义在类中、方法外的变量。
  • 基本类型:基本类型包括整形、浮点型、字符型和布尔型四大类共8种类型。
  • 引用类型:类类型、接口类型和数组类型都是引用类型。所有的引用类型在使用前都需要为其分配内存空间(new)。

3、引用类型中包装的基本类型拥有默认值(为0、null、false),包括成员变量、数组等。

Day5

1、运行时加载到内存中时发生了什么?
见笔记JVM内存模型
2、数组(对象)建立的4个方法:

  1. // 动态初始化(指定长度,自动初始化值)
  2. int[] a = new int[3]; // 分配内存并指定长度
  3. // 静态初始化(指定值,自动分配长度)
  4. int[] b = new int[]{1, 2, 3}; // 通过赋值自动分配长度
  5. int[] c = {1, 2, 3}; // 简便的方式
  6. int[] d; d = new int[]{1, 2, 3}; // 先定义再分配内存

两个错误方法:

  1. int[] a = new int[3]{1, 2, 3}; // 边赋值边指定长度
  2. int[] b; b = {1, 2, 3}; // 未分配内存就赋值

3、复制数组需要使用java.lang.System类中的arraycopy方法,而不是使用
int[] a = b; //只是将b的地址给了a,操作的还是相同的内存(浅拷贝)
扩充数据需要通过复制数组再赋值指针的方式进行

  1. int[] c = new int[b.lenth * 2] // 将长度扩充为原来2倍
  2. System.arraycopy(b, 0, c, 0, b.lenth); // 5个参数分别是源数组/初索引/新数组/初索引/长度(深拷贝)
  3. b = c; // 将新数组c的指针赋给b

Day6

无。

Day7

1、static修饰符:
有static的方法和变量——属于类的——存储在方法区——能够直接调用(Test.main)
无static的方法和变量——属于对象——存储在堆————只能用对象调用,每个对象的不一样(new Test().main)
2、虚拟机内存模型:见笔记JVM内存模型

=====基础笔记完结=====