Java基础知识复习


复习

1. Java编译和运行

public class Main{
    public static void main(String[] args) {
        System.out.println("hello world!");
    }
}

假设Java代码文件名为Main.java

  • 通过 javac 文件名(需要带后缀)编译Java代码文件生成一个.class的字节码文件一个class类生成一个.class文件

    javac Main.java
    
    • 如果代码里包含中文想解决乱码就需要在编译时指定编码格式-encoding

      javac -encoding Main.java
      
  • 一个Java文件只能包含一个public类一但这个类被public所修饰那么这个类名要和文件名相同

  • 通过java 文件名运行Java文件文件名不需要带后缀

    java Main
    
  • String[] argsargs是一个数组也是Java运行时参数

    下面的代码只要在java命令运行时文件名后面加上参数就能存放导 args数组中并打印出来

    java Main 1 2 3
    
    public class Main{
        public static void main(String[] args) {
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
            }
        }
    }
    

2. Java运行环境

一个Java代码也就是一个.java文件通过编译生成一个.class

  • JDK(Java开发者工具)

    Java开发工具包提供给Java程序员使用包含了JRE同时还包含了编译
    器javac与自带的调试工具Jconsole、jstack等

  • JRE(Java运行时环境)

    • Java运行时环境包含了JVMJava基础类库。是使用Java语言编写程
      序运行的所需环境
  • JVM(Java虚拟机)

    • 编译完的.class文件是跑在Java虚拟机上的JVM也是Java跨平台的关键。

在这里插入图片描述

3. Java注释

  • 单行注释

    public class Main{
        // 单行注释
        public static void main(String[] args) {
            System.out.println("hello");
        }
    }
    
  • 多行注释

    public class Main{
        /*
        多
        行
        注
        释
         */
        public static void main(String[] args) {
            System.out.println("hello");
        }
    }
    
  • 文档注释

    文档注释也时多行注释的一种

    public class Main{
        /**
         * 文档注释
         * @param args
         */
        public static void main(String[] args) {
            System.out.println("hello");
        }
    }
    

4. Java中的打印

  • 打印且换行

    System.out.println();
    
  • 打印不换行

    System.out.print();
    
  • 格式化打印

    Java中也提供了和C语言类似的格式化打印

    System.out.printf("%d\n",10);
    

5. 数据类型

在Java中一共有8种数据类型8种数据类型都分别对应各自的包装类。且在Java中不存在无符号数无论在什么平台上数据类型的大小都是一致的这也是Java跨平台的体现。

数据类型所占内存空间对应包装类
int4个字节Integer
long8个字节Long
float4个字节Float
double8个字节Double
char2个字节Character
short2个字节Short
booleanJVM中没有规定大小Boolean
byte1个字节Byte

比如int能表示的数据范围为 − 2 31   2 31 − 1 -2^{31}~2^{31}-1 231 2311那拿int的最大值加上1会发生什么或者拿int的最小值减去1又会发生什么

public class Main{
    public static void main(String[] args) {
        int max = Integer.MAX_VALUE;/
        int min = Integer.MIN_VALUE;
        System.out.println(max);
        System.out.println(min);
        System.out.println("========");
        System.out.println(max+1);
        System.out.println(min-1);
    }
}

运行结果

2147483647
-2147483648
========
-2147483648
2147483647

我们发现最大值+1变成了最小值最小值-1变成了最大值其它基本数据类型也时存在的(浮点数除外)。

在这里插入图片描述

又或者是

public static void main(String[] args) {
        int a = 128;
        byte b = (byte)a;
        System.out.println(b);
    }

打印结果

-128

整形

Java中短整形short有整形int和长整形long如果要声明一个整形是长整形只需在数字后面加上L或者l(建议使用大写L)

short a = 10;
int b = 20;
long c = 30;
long d = 40L;
long f = 50l;

浮点型

Java中有单精度浮点型float和双精度浮点型double,注意在Java中浮点数默认是double类型。所以如果要使用float就得在变量后面加上F来声明这是一个float类型的数字或者使用强制类型转换。

float a = 3.14f;
float b = 3.14F;
float c = (float)3.14;

字符类型

在Java中用char表示字符型Java中字符采用Unicode编码一个字符占两个字节。且可以保存一个汉字一个汉字也是占两个字节。需要注意char类型在Java中是不能够给负数的

char ch = '好';
char c = 'a';
char n = 100;

字节类型

在Java中有一个字节类型byte它占一个字节对标的是C语言中的char取值范围为-128~127

byte a = 127;
byte b = -128;

来看一段代码

public class Main{

    public static void main(String[] args) {
        byte b1 = 10;
        byte b2 = 20;
        byte b3 = 10+20;
        byte b4 = b1+b2;//编译错误
        byte b5 = b1 + 1;//编译错误
    }
}

这段代码byte b4 = b1+b2;byte b5 = b1 + 1;都会编译错误而前面的byte b3 = 10+20;并没有报错这是为什么呢

  • b3不报错是因为在编译期间就被替换成byte b3 = 30;了所以不会报错
  • b4报错是因为编译器不确定b1和b2里的值是啥因为它们两个是变量所以为了安全编译器就会报错。
  • 而b5报错就牵扯到类型提升了计算机在读取数据的时候都是4个字节来读取的在计算的时候当一个数据不足4个字节时为了提高计算速度就会进行整形提升将byte提升成int类型。

布尔类型

boolean的取值只能是true或者false

boolean flag = false;
boolean t = true;

数据类型转换

强制类型转换

public static void main(String[] args) {
        double a = 3.14;
        int b = (int)a;
 }
  1. 强制类型转换可能会导致精度丢失. 如刚才的例子中, 赋值之后,3.14 就变成 3 了, 小数点后面的部分被忽略.
  2. 强制类型转换不是一定能成功, 互不相干的类型之间无法强转比如int和booean之间就不能进行强制类型转换。

隐式类型转换

java 作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验.

public static void main(String[] args) {
        double a = 3.14;
        long b = 10L;
        int c = 20;
        
        a = b;
        a = c;
        b = c;
        // 下面写法都是错误的
        b = a;
        c = b;
        c = a;
    }

结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行.

从上往下说明double可以接收它下面的所有类型。

注意char比较特别因为它不能接收负数所以char不能接收byte的值。

double a = 3.14;
float b = (float)1.23;
long c = 10;
int d = 20;
short e = 30;
char f = 10;
byte g = 6;
  1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型.
  2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失.
  3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查.

小结

注意事项

Java是一个强类型语言在使用数据类型的时候需要注意。

  • 数字默认是整形
  • 小数默认是double类型
  • 不要把char类型和整形挂勾char是不能够接受负数的
  • 在给变量赋值时不能超过它的数据范围
  • byte类型其实对应的是C语言的char类型
  • boolean的值只能是True或者False
  • boolean类型的大小由于没有规定有的书上书上说是1个位或者说一个字节。
  • char采用Unicode编码占两个字节
  • 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算
  • 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型.
  • 局部变量在使用之前一定要初始化

6. 变量命名规范

  • Java的变量名可以有数字母下划线和$符组成但不能以数字开头。
  • 关键字不能作为变量名
  • 变量名一般以小驼峰形式(多个单词除第一个外其他单首字母大小

7. 运算符

算数运算符

+、-、*、/、%,没啥好说的。

注意点在Java中是可以对浮点数使用%的且0不能作为除数不然会抛出异常。

public static void main(String[] args) {
    double num = 1.25;
    System.out.println(num%1);
}
//输出0.25

还有+=、-=、/=、*=、%=、>>=、<<=、>>>=

代码示例:

下面这段代码b = b+a;编译错误b += a;正常运行是因为+=自动进行了强制类型转换

public static void main(String[] args) {
    long a = 10;
    int b = 20;
    b = b+a;//编译错误
    b += a;// 正常运行
}

逻辑运算符

逻辑运算符有:

  • 逻辑与&&短路与

  • 逻辑或||短路或

  • 逻辑非!只能对布尔类型使用

  • 对于 && , 如果左侧表达式值为 false, 则表达式的整体的值一定是 false, 无需计算右侧表达式

  • 对于 ||, 如果左侧表达式值为 true, 则表达式的整体的值一定是 true, 无需计算右侧表达式

  • &| 如果操作数为 boolean 的时候, 也表示逻辑运算. 但是和 && 以及 || 相比, 它们不支持短路求值

移位运算符

  • 左移<<最高位不要末尾补0
  • 右移>>最低位不要最高位补符号位
  • 无符号右移>>>最低位不要最高位补0

关系运算符

== != < > <= >= 都是关系运算符它们的返回值都是boolean类型

8. switch

long float double boolean 都不可以作为switch的参数

除了这些基本数据类型后续说道的枚举enumString也可以作为Switch的参数

9. 方法

方法的重载

重载的要求

  • 方法名相同
  • 方法的参数类型和个数不相同
  • 返回值是不做要求的

可变参数变程

在Java中存在一种非常特殊的语法可变参数编程就是一个方法的参数我们不知道有几个的时候可以使用int...这种类型来接收1个或者多个整形变量。

public class Main {
    public static int sum(int... array) {
        int sum = 0;
        for (int num : array) {
            sum += num;
        }

        return sum;
    }
    public static void main(String[] args) {
        System.out.println(sum(1));
        System.out.println(sum(1,2));
        System.out.println(sum(1,2,3));
        System.out.println(sum(1,2,3,4));
        System.out.println(sum(1,2,3,4,5,6,7,8,9,10));
    }

}

方法的调用

方法的调用实在栈的也就是JVM中的Java虚拟机栈局部变量也是在栈栈开辟空间。

  • 在Java中是拿不到栈上的地址的但能拿到堆区的地址
  • 每一次函数的调用操作系统都会在内存的栈区上开辟一块空间称为栈帧
  • 栈区的空间是有限的如果一个方法递归程度过深就会出现栈溢出异常。

假设有这么一段代码

public class Main {
    public static int Add(int x, int y)
    {
        int z = 0;
        z = x + y;
        return z;
    }

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = Add(a, b);
    }

}

在这里插入图片描述

10. 数组

一维数组的创建方式

注意等号左边的[]里是不能写数字的

public static void main(String[] args) {
        int[] arr1 = {1,2,3,4,5};
        int[] arr2 = new int[]{1,2,3,4,5};
        int[] arr3 = new int[5];//定义未使用里面的元素默认是0
        int[] arr4;//未初始化不能使用
        //这种写法也是可以的
        int arr[] = {1,2,3,4,5};
    }

一维数组在内存中的存储

假设有这么几个数组它们是在哪存储的

int[] arr1 = {1,2,3,4,5};
int[] arr2 = new int[]{1,2,3,4,5};
int[] arr3 = new int[5];

我们知道局部变量是在栈上开辟空间的而只要new了的就会在堆上开辟内存。

堆上的对象是由JVM自动回收的回收的原则是如果当前对象没有人引用的时候JVM的垃圾回收器就会自动回收该对象

其实向arr1这些数组名其实就是一个变量它是一个引用存放的是数组的地址简单来说就是arr1是一个引用它指向了一个数组对象。

我们可以直接打印数组名就得到一个地址但这个地址不是真实的地址而是通过hash得到的一个唯一的地址。

在这里插入图片描述

数组的拷贝

以下几种方式其实都是浅拷贝但如果单纯的拷贝基本数据类型那也算是深拷贝。

数组的拷贝一共有三种方式

  • Arrays.copyOf(原数组, 新数组长度)
public static int[] copyOf(int[] original, int newLength) {
        int[] copy = new int[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
  • System.arraycopy(原数组,原数组起始下标,目标数组,目标数组其实下标要拷贝的长度)

    public static native void arraycopy(Object src,  int  srcPos,
                                            Object dest, int destPos,
                                            int length);
    

    这种native方法是本地方法运行在本地方法栈上的底层是由C/C++实现速度快。而上面的copyOf函数的实现也是调用这个方法

  • 数组名.clone

    这种方法是直接产生一个新的副本

一维数组的打印

一维数组的三种打印方式

public class Main {

    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};

        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();
        for (int tmp : array) {
            System.out.print(tmp+" ");
        }
        System.out.println();
        System.out.println(Arrays.toString(array));
    }

}

二维数组的创建

int[][] array1 = {{1,2,3},{4,5,6}};
int[][] array2 = new int[2][3];
int[][] array3 = new int[][]{{1,2,3},{4,5,6}};

二维数组在内存中的存储

在Java中二维数组的每一行都是一个一维数组每一行存的都是对应一维数组的地址。

假设有那么一个数组

int[][] array1 = {{1,2,3},{4,5,6}};

在这里插入图片描述

二维数组的打印

三种打印二维数组的方式

public class Main {

    public static void main(String[] args) {
        int[][] array = {{1,2,3},{4,5,6}};
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
        for (int[] arr: array) {
            for (int tmp : arr) {
                System.out.print(tmp+" ");
            }
            System.out.println();
        }
        System.out.println(Arrays.deepToString(array));
    }

}

`

在这里插入图片描述


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java