美文网首页中北软院创新实验室程序员
Java Core 那些你必须知道的内容

Java Core 那些你必须知道的内容

作者: HikariCP | 来源:发表于2018-03-27 10:10 被阅读77次

    注释

    • 注释在编译时全被删除。

    常量和变量运算符

    • 类型转换原则:占用内存小的类型向占用内存大的类型进行转换,这样能保证不丢失精度。(扩容)

    • 只要是整数就是int型。赋值运算会进行自动强转,纯算数运算也会自动强转,但算数运算且含有变量时不会自动强转。

      • Bytea = 4;实际上JVM首先会检查4这个int型的数字是否超过byte的长度,若没超过则自动进行强制转化,若超过了就报错。
      • 如下这样,便是上面所说,含有变量的自动强转不会成功。
          byte a = 4,b = 5;
          Byte c = a + b; //此时会报错,因为在JVM解析时a,b是int型。但是以变量形式强转转byte型不会成功。这种变量式除非带上 (byte)!
      
    • 类型强转:内存占用多的字段向占用小的转化

    • 自动转型: 所占内存小的类型赋值给所占内存大的类型

    • byte数值范围是-127 - 128即1个字节8位所表示的最大范围。所以在程序中int b = 129; byte c = (byte) b;这样在进行强转的时候是会出现精确度丢失的问题的。因为强转操作的原因,使得超出了byte范围的变量b,129丢失精确度。

    • ASCLL表值0-48,A-65,a-97

    • “Hello”instanceof String 判断Hello对象是否是String类类型的

    • a>0||a<10左边一旦为true,右边不计算了,结果就是true。所以如果判断语句中使用的话,就需要把一些耗时操作放到||右面,来尽可能节省时间。

    • ||优点:|||效率高了一点点

    • 局部代码块中的局部变量生命周期:在局部代码块中被创建,到"}"时结束。

    • 函数中的其他局部变量只有当函数执行完后,函数从方法区中消失,紧接着函数中所有的局部变量从栈内存中消失。

    • \n:回车,\t:制表符,\b:退格, \r:按下回车键,
      Windows中回车符: \r\n,Linux中回车符: \n
      \”:在字符串中使用双引号

    • break 跳出,只跳出循环语句。

    • continue 跳过,跳过当前次循环。只跳过循环

    • 数组:int[] a = new int[3] -- 类型 对象 = 声明对象[指定大小]

      • 数组也是对象,存放在堆内存中
    • 堆内存:存储数组和对象和成员变量。成员变量即declare在类中的变量。而不是声明在函数或循环体判断体中的局部变量。

    • 栈内存: 存储局部变量,变量所属的作用域运行结束,该变量就自动释放空间。for、while、do-while、函数、局部代码块中的变量都是局部变量

    • int[] arr = new int[3] 代码在扫描到这一行的时候。JVM会首先在栈内存中declare一个int[] a的引用变量。接着执行new int[3],在堆内存中开辟一块儿连续的内存空间。存储在堆内存中的对象都有首地址,=即把堆内存中new int[3]对象的首地址赋予了a变量。从而建立起了从引用变量->对象堆内存首地址的关系。

      • arr = null;即把栈内存中的引用变量arr指向堆内存对象的地址指针去掉,使他们断开联系。此时堆内存中的new int[]3由于没有引用变量指向它,就可视为garbage,等待JVM的回收。
      • 第一种定义方式:int[] arr = new int[3]
      • 第二种定义方式:int[] a = new int[]{89,20,300}
      • 第三种定义方式:int[] a = {89,20,300}
      • 选择第一种定义方式:需要一个容器,知道容器的大小,但不明确容器中的数据。选择第二、三种定义方式:需要一个容器,而且数据已知。
    • int[][] a = new int[3][2] 首先JVM的程序计数器扫到这行代码的时候。加载执行,JVM首先在栈内存中declare一个变量a初始化地址为null,所以a即为引用变量。然后此时JVM运行new int[3][2],会现在堆内存中和new int[3]一样开辟3块连续的内存空间,不同的是new int[3]开辟的是一块而new int[3][2]开辟的是3块连续的空间。然后在每一块内存空间中会写入容量为[2]的小数组的内存地址。此时再开辟开辟三个容量为2的一维数组。将首地址赋予3个大数组的内存空间中。然后将大数组的起始地址赋予栈内存中的引用变量a需要注意的是:外层数组的内存地址并不是像内数组一样连续的。

      • 第一种定义方式:int[][] arr = new int[3][2]
      • 第二种定义方式:先给大数组初始化,在分别给小数组初始化。
      int[][] arr =new arr[3][];//只给大数组分配3个连续空间
      arr[0] = newint[2];
      arr[1] = newint[1];
      arr[2] = newint[3];
      
      • 第三种定义方式:二维数组中每个小数组长度可以不一样。int[][] arr = {{1,2,3},{2,3},{1}}
      • 二维数组的输出:
      int[][]arr = new int[3][];
      System.out.println(arr);//输出:[[@c1f3fe
      System.out.println(arr[0]);//输出:null 由于内数组中内存空间中存储的是外数组空间地址的首地址的hash值,但此时外数组还没有分配内存空间。所以空间地址为null
      System.out.println(arr[0][0]);//发生空指针异常!,因为外数组内存空间还没有分配,直接获取肯定为Exception。
      
    • 高效计算2*82 * 8尽量转化成2 << 3,这样效率高。速度快,因为在计算机中说白了所有的运算最后都会转化成移位加法运算。所以这种方式效率高,不进行相乘相加操作,只要向左移位即可。

      • 除法转成乘法,乘法转成加法,减法也转成加法

    • 将两个值互换,不借助第三个变量:

      • 第一种方法:
      int a = 3,b = 4;
      a = a + b;
      b = a - b; 
      a = a - b;
      
      • 第二种方法:
      int a = 3, b = 4;
      a = a ^ b; // 3 ^ 4
      b = a ^ b; // 3 ^ 4 ^ 4
      a = a ^ b; // 3 ^ 4 ^ 3
      

    相关文章

      网友评论

      • 半夏风痕:“接着执行new int[3],在堆内存中开辟一块儿连续的内存空间。”这个开辟的内存空间,不一定是连续的吧?
        HikariCP:@半夏风痕 多谢支持😁
        半夏风痕:额,我错了,没注意到对象是数组类型的

      本文标题:Java Core 那些你必须知道的内容

      本文链接:https://www.haomeiwen.com/subject/wdsjcftx.html