小言_互联网的博客

Java基础知识复习

431人阅读  评论(0)


复习

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运行时环境,包含了JVM,Java基础类库。是使用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跨平台的体现。

数据类型 所占内存空间 对应包装类
int 4个字节 Integer
long 8个字节 Long
float 4个字节 Float
double 8个字节 Double
char 2个字节 Character
short 2个字节 Short
boolean JVM中没有规定大小 Boolean
byte 1个字节 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));
    }

}

 

`



转载:https://blog.csdn.net/weixin_53946852/article/details/128634552
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场