当前位置: 首页 > article >正文

【Java SE】基础知识1

本文主要是对 Java SE 部分比较重要和容易错的知识点作了提炼

目录

1.Java开发注意事项和说明

2.相对路径、绝对路径

3.转义字符

4.变量

4.1 数据类型

4.2 变量使用注意事项

4.3 浮点数的使用陷阱

4.4 char类型的使用细节

4.5 字符编码表的基本介绍

4.5.1 ASCII编码表

4.5.2 Unicode编码表

4.5.3 UTF-8编码表

​编辑

4.5.4 其他编码表

4.6 基本数据类型转换

4.6.1 自动类型转换

4.6.2 强制类型转换

4.6.3 String类型转换

5.位运算符与二进制

5.1 原码、反码、补码(重点)

5.2 位运算符

5.3 例子(重要)

6.数组、排序

6.1 一维数组的使用

6.1.1 动态初始化数组

6.1.2 静态初始化数组

6.2 一维数组的注意事项和细节

6.3 数组赋值机制(重要)

6.4 数组拷贝

6.5 冒泡排序

6.6 二维数组

6.6.1 初始化方法

6.6.2 二维数组的内存布局(重要) 


1.Java开发注意事项和说明

(1)Java 源文件以 .java 为后缀名。源文件的基本组成部分是类(class)

(2)Java 应用程序的执行入口是 main 方法。它的固定书写方式为:

    public static void main(String[] args) {}

(3)一个源文件最多只能有一个 public 类,其他类的个数不限.但是如果该源文件中有多个类,编译后则会生成多个 .class 文件,每个类对应一个 class 文件,如下图所示:

(4)如果源文件包含一个 public 类,则文件名必须按该类名命令

(5)main 方法通常在 public 类中,当然也可以把 main 方法写在非 public 类中,然后指定运行非 public 类,这样入口方法就是非 public 类的 main 方法

2.相对路径、绝对路径

相对路径:从当前目录开始定位,形成的一个路径

绝对路径:从顶级目录开始定位,形成的一个路径

下面看个例子更容易理解一点

相对路径、绝对路径例子 

当前所在位置:D\abc1\test 访问 D\abc2\test\hello.txt 

相对路径方式访问:

绝对路径方式访问:

3.转义字符

作用
\t制表位,可以实现对齐功能
\n换行符
\\表示一个\
\"表示一个"
\'表示一个'
\r回车

Java常用的转义字符

代码示例:

public class Main {
    public static void main(String[] args) {
        // \t:一个制表位,实现对齐的功能
        System.out.println("北京\t天津\t上海");
        // \n:换行符
        System.out.println("jack\nsmith\nmary");
        // \\:一个\
        System.out.println("C:\\Windows\\System32\\cmd.exe");
        // \" :一个"
        System.out.println("老韩说:\"要好好学习 java,有前途\"");
        // \':一个'
        System.out.println("老韩说:\'要好好学习 java,有前途\'");
        // \r :一个回车
        System.out.println("韩顺平教育\r北京");//回车把韩顺平教育覆盖了,输出北京
    }
}
/*输出结果
北京	天津	上海
jack
smith
mary
C:\Windows\System32\cmd.exe
老韩说:"要好好学习 java,有前途"
老韩说:'要好好学习 java,有前途'
北京
 */

4.变量

变量相当于内存中一个数据存储空间的表示,可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量(值)

4.1 数据类型

Java数据类型 

[1]:占用 1 个字节 


4.2 变量使用注意事项

(1)变量表示内存中的一个存储区域,不同的变量,类型不同,占用的空间大小不同,比如 int 数据类型占用 4 个字节,double 数据类型占用 8 个字节

(2)该区域有自己的名称(变量名)和类型(数据类型)

(3)变量必须先声明,后使用

(4)变量 = 变量名 + 值 + 数据类型

(5)该区域的数据/值可以在同一类型范围内不断变化:

public class Main {
    public static void main(String[] args) {
        int a = 50;
        a = "jack";//X
        a = 100//✔
    }
}

(6) 变量在同一个作用域内不能重名

public class Main {
    public static void main(String[] args) {
        int a = 50;
        System.out.println(a);
        int a = 70;//X,变量在同一作用域内不能重名 
    }
}
class dog {
    int a = 70;//✔,在不同作用域,可以重名
}

4.3 浮点数的使用陷阱

 先看一段代码

public class Main {
    public static void main(String[] args) {
        double num1 = 2.7;
        double num2 = 8.1 / 3;
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);//不是2.7,而是非常接近2.7的一个小数,值是2.6999999999999997
}
//输出结果
//num1 = 2.7
//num2 = 2.6999999999999997

 可以看到, 8.1 在数学中是可以被 3 整除的,得到 2.7。但在 Java 中并没有被整除

因此当对计算结果是小数的值进行相等判断时,应该是以两个数的差值的绝对值在某个精度范围内判断,代码如下

public class Main {
    public static void main(String[] args) {
        double num1 = 2.7;
        double num2 = 8.1 / 3;
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);//不是2.7,而是非常接近2.7的一个小数,值是2.6999999999999997

        //错误写法
        if (num1 == num2) {
            System.out.println("相等");
        }

        //正确写法
        if (Math.abs(num1 - num2) < 0.000001) {
            System.out.println("差值非常小,到我规定精度范围内,认为相等");
        }
    }
}
//输出结果
num1 = 2.7
num2 = 2.6999999999999997
差值非常小,到我规定精度范围内,认为相等

 如果是直接赋值的小数,不是通过计算得来的,那可以直接判断是否相等,如下所示

public class Main {
    public static void main(String[] args) {
        double num1 = 2.7;
        double num2 = 2.7;
        if (num1 == num2) {
            System.out.println("两数相等");
        }
    }
}
//输出结果
两数相等

4.4 char类型的使用细节

(1)字符类型可以表示单个字符,也可以存放汉字,多个字符用字符串String

(2)字符常量是用单引号 '  ' 括起来的单个字符。例如:char c1 = 'a',char c2 = '中'

(3)Java 中还允许使用转义字符  '\'  来将其后的字符转变为特殊字符型常量

public class Main {
    public static void main(String[] args) {
        char a = '\n';
        System.out.print("1" + a);
        System.out.print("1");
    }
}
/*输出结果
1
1
*/

(4)char 的本质是一个整数,但在输出时,是 unicode 码对应的字符。

char 赋一个整数,输出时会按照对应的 unicode 字符输出

char 赋一个字符,输出时可以其转换为整型,转换结果即该字符对应的 unicode

示例代码:

public class Main {
    public static void main(String[] args) {
        char c1 = 97;
        char c2 = 106;
        char c3 = 39532;
        System.out.println("97对应的字符:"+c1);
        System.out.println("106对应的字符:"+c2);
        System.out.println("39532对应的字符:"+c3);
        System.out.println("------------------");

        char c4 = '马';
        char c5 = 'a';
        System.out.println("\'马\'对应的unicode码:"+(int)c4);
        System.out.println("a对应的unicode码:"+(int)c5);
    }
}
/*输出结果
97对应的字符:a
106对应的字符:j
39532对应的字符:马
------------------
'马'对应的unicode码:39532
a对应的unicode码:97
*/

(5) char 类型可以进行运算,相当于一个整数,因为它都对应有 Unicode

public class Main {
    public static void main(String[] args) {
        //char类型是可以进行运算的,相当于一个整数
        System.out.println('a' + 10);//107
        
        char c5 = 'b' + 1;//字符'c'
        System.out.println(c5); //字符'c'
        System.out.println((int)c5); //字符'c'对应的unicode码99
    }
}
/*输出结果
107
c
99
*/

4.5 字符编码表的基本介绍

字符型存储到计算机中,需要将字符对应的码值(整数)找出来

比如对于 'a' 字符计算机的存储和读取如下:

字符和码值的对应关系是通过字符编码表(人为规定的)决定的,下面有几种字符编码表,如今 UTF-8 使用最多


4.5.1 ASCII编码表

上个世纪 60 年代美国使用一个字节指定了一套字符编码,对英语字符与二进制位之间的关系做了统一规定。但 ASCLL 码表一共只规定了 128 个字符的编码,对于一个字节没有全部用完(对于美国人来说够了,因为它们的母语是英文,英文字母大小写加起来总共也才 52 个),一个字节最多可规定  \color{red}2^8 个字符的编码

ASCll码表 

 缺点:不能表示所有字符,如果要表示其他国家的文字显然一个字节是不够的

4.5.2 Unicode编码表

使用两个字节构造 Unicode 编码表,\color{red}2^{16}=65536,所以做多编码是 65536 个字符,该数量足以将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码。

但其中一个英文字母和一个汉字都占用 2 个字节,这对于存储空间来说是浪费(因为英文字母其实一个字节就足够了)

Unicode编码表 0-127 的字符与 ASCll 的编码一致,比如 'a'ASCll 码是 0x61 ,在 Unicode 码是 0x0061,转换为十进制都是 97,因此 Unicode 码兼容 ASCll

4.5.3 UTF-8编码表

UFT-8 是互联网上使用最广的一种编码表,是 Unciode 表的改进,是一种变长的编码方式,可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度

其中,字母占 1 个字节,汉字占 3 个字节。这里可以做一下测试,创建一个 demo.txt 文件,在文件中输入 "abc马",查看文件大小验证

3 个字母 + 1 个汉字 = 6 字节


4.5.4 其他编码表

gbk:可以表示汉字,而且范围广,字母使用 1 个字节,汉字 2 个字节

gb2312:可以表示汉字,gb2312 < gbk

big5码:繁体中文,台湾,香港

4.6 基本数据类型转换

4.6.1 自动类型转换

自动类型转换:当 Java 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的类型

下图是两种自动类型转换路线

自动类型转换

注: byte、short、char 不会相互自动转换 

自动类型转换规则 

 (2)精度大的数据类型赋值给精度小的数据类型会报错,反之就会进行自动转换

public class Main {
    public static void main(String[] args) {
        int a = 1.1;//X,double->int
        int b = 'c';//✔,char->int
    }
}

(3) 编译器规定:(byte、short)char 之间不能相互自动转换

public class Main {
    public static void main(String[] args) {
        byte b1 = 10 ;
        char c1 = b1 ; //X,byte->char
        
        char c2 = 'a';
        short s1 = c2; //X,char->short
    }
}

(4)byte、short、char 它们三者可以计算,在计算时首先转换为 int 类型,其计算结果也用 int 类型数据

byte + short->int,byte + char -> int,short + char -> int

byte + byte -> int,short + short -> int,char + char -> int

public class Main {
    public static void main(String[] args) {
        byte b1 = 10;
        short s1 = 10;
        short s2 = b1+s1;//X,byte+short->int
        int result = b1+s1;//✔
    }
}

(5) 自动提升原则:表达式结果的类型自动提升为操作数中精度最大的类型

public class Main {
    public static void main(String[] args) {
        byte b = 1;
        short s = 100;
        int a = 200;
        double d = 1.1;
        Object obj = b + s + a + d;//Double数据类型
        if (obj instanceof Double) {
            System.out.println("运算结果为Double数据类型");
        }
    }
}
//输出结果
//运算结果为Double数据类型

4.6.2 强制类型转换

强制类型转换:即自动类型转换的逆过程,将精度大的数据类型转换为精度小的数据类型,但可能造成精度降低或溢出问题,强制类型转换需要程序员手动实现

强制类型转换示例

 (1)精度降低和数据溢出例子

public class Main {
    public static void main(String[] args) {
        //精度降低
        int a1 = (int) 1.9;
        System.out.println(a1);
        //数据溢出
        int a2 = 2000;
        byte b = (byte) a2;
        System.out.println(b);
    }
}
/*输出结果
1
-48
 */

(2) char 类型可以保存 int 的常量值,但不能保存 int 的变量值,需要强转

public class Main {
    public static void main(String[] args) {
        char c1 = 100;//✔
        int m = 100;//✔
        char c2 = m;//X,m是int类型
        char c3 = (char) m;//✔
        System.out.println(c3);//100对应的字符 -> d
    }
}

4.6.3 String类型转换

(1)基本数据类型  ->  String : +"" 即可

public class Main {
    public static void main(String[] args){
        int n1 = 100;
        float n2 = 1.1f;
        double n3 = 2.2;
        boolean n4 = true;
        String str1 =n1+"";
        String str2 =n2+"";
        String str3 =n3+"";
        String str4 =n4+"";
        System.out.println(str1+" "+str2+" "+str3+" "+str4);
    }
}
/*输出结果
100 1.1 2.2 true
 */

(2)String -> 基本数据类型 :使用基本数据类型对应的包装类的方法,得到基本数据类型

public class Main {
    public static void main(String[] args){
        String s = "123";
        int num1 = Integer.parseInt(s);
        double num2 = Double.parseDouble(s);
        float num3 = Float.parseFloat(s);
        long num4 = Long.parseLong(s);
        byte num5 = Byte.parseByte(s);
        boolean bool = Boolean.parseBoolean("true");
        short num6 = Short.parseShort(s);

        System.out.println(num1);//123
        System.out.println(num2);//123.0
        System.out.println(num3);//123.0
        System.out.println(num4);//123
        System.out.println(num5);//123
        System.out.println(bool);//true
        System.out.println(num6);//123
    }
}

5.位运算符与二进制(非常重要)

现代的计算机技术全部采用的是二进制,因为它只使用 0、1 两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的,用 0、1 两个数字及其组合来表示任何数

5.1 原码、反码、补码

Java 没有无符号数,所以我们只针对有符号数作说明

  • 二进制的最高位是符号位,0 代表正数,1 代表负数
  • 正数的原、反、补码均一致
  • 负数反码 = 原码符号位不变,其他位取反
  • 负数补码 = 反码 + 1
  • 负数反码 = 负数补码 - 1
  • 0 的反码、补码都为 0

超级重点:在计算机作运算时,都是以补码的方式来计算的。当看运算结果时,要看它的原码(后面会举例子)

5.2 位运算符

Java 中有 7 个位运算符

运算规则
&两位全为 1 ,结果为 1 ,否则为 0
|两位有一个为 1 ,结果为 1 ,否则为 0
^相同为 0 ,相异为 1
~按位取反,0 --> 1,1 --> 0
>>算数右移:符号位不参与移位,低位舍弃,并在高位补符号位。本质:每右移1位,相当于除以 2
<<算数左移:符号位不参与移位,高位舍弃,低位补 0 。本质:每左移 1 位,相当于乘以 2
>>>逻辑右移:符号位参与移位,低位舍弃,高位补 0

注意:没有 "<<<" 运算符

5.3 例子(必看)

2&3、~2 计算机的运算过程 

2&3、~2 计算机的运算过程

1>>2、1<<2 计算机的运算过程

1>>2、1<<2 计算机的运算过程

逻辑右移 -1>>>2 计算机的运算过程:

-1 >>>2计算机的运算过程 

6.数组、排序

6.1 一维数组的使用

6.1.1 动态初始化数组

public class Main {
    public static void main(String[] args){

        //第一种动态初始化方法,double[] scores 或者 double scores[]都可以
        double scores[] = new double[5];
        Dog dogs[] = new Dog[5];
        for (int i = 0; i < scores.length; i++) {
            scores[i]=95+i;
        }

        //第二种动态初始化方法
        double scores1[];
        scores1=new double[5];
        Dog dogs1[];
        dogs1=new Dog[5];
    }
}
class Dog{
    String name;
    int age;
}

6.1.2 静态初始化数组

public class Main {
    public static void main(String[] args){
        //静态初始化方法
		int a[]={1,2,3,4,5,6,7,8};
    }
}

6.2 一维数组的注意事项和细节

(1)数组是多个相同类型数据的组合,数组属于引用类型

(2)数组中的元素可以是任何数据类型,包括基本类型、引用类型,但是不能混用

public class Main {
    public static void main(String[] args){
        String str[] = new String[5];
        Dog dogs[] = new Dog[5];
    }
}

class Dog{
    String name;
    int age;
}

(3) 数组创建后,如果没有赋值,有默认值

  • int、short、byte、long:0
  • double、float:0.0
  • boollean:false
  • String:null
  • char:'0'

6.3 数组赋值机制(重要)

基本数据类型的赋值方式为值拷贝(值传递),其赋值机制如下图所示

值拷贝 

 数组是引用数据类型,数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用赋值

public class Main {
    public static void main(String[] args) {
        //数组在默认情况下引用传递,赋的值是地址,赋值方式为引用赋值
        //arr2 = arr1,即将arr1数组的地址赋值给了arr2,所以arr2变化arr1也会作相应改变
        int[] arr1 = {4, 5, 6};
        int[] arr2 = arr1;
        arr2[0] = 10;
        //查看arr1的值
        for (int i = 0; i < arr1.length; i++) {
            System.out.print(arr1[i]+" ");
        }
    }
}
/*输出结果
10 2 3
 */

其赋值机制如下图所示

地址拷贝 

6.4 数组拷贝

目标:将int[] arr1 = {4,5,6},拷贝到 arr2 数组,要求数据空间是独立的

方法:arr2 数组开辟一个新的空间,遍历 arr1 数组将每个元素的值拷贝给 arr2 即可

public class Main {
    public static void main(String[] args) {
        int[] arr1 = {4, 5, 6};
        int[] arr2 = new int[arr1.length];
        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = arr1[i];
        }
    }
}

6.5 冒泡排序

冒泡排序的特点:

(1)若一共 k 个元素,外层循环只需要进行 k-1 次,即 k-1 轮排序

(2)每一轮排序可以确定一个元素的最终位置。比如第 1 轮排序确定最大数的位置,第 2 轮排序确定第 2 大的数的位置...

public class Main {
    public static void main(String[] args) {
        //冒泡排序,实现从小到大排序
        int arr[]={24,69,80,57,13};
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j <arr.length-i-1; j++) {
                if(arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

6.6 二维数组

6.6.1 初始化方法

public class Main {
    public static void main(String[] args) {
        //第一种动态初始化方法
        int[][] arr1 = new int[3][3];

        //第二种动态初始化方法
        int[][] arr2;
        arr2 = new int[3][3];
        
        //第三种动态初始化方法
        int[][] arr3 = new int[3][];
        //遍历arr3每个一维数组,给每个一维数组开空间
        for(int i = 0; i < arr3.length; i++) {
        	arr[i] = new int[i+1]
        }
        
        //静态初始化方法
        int[][] arr3 = {{1,2,3},{4,5,6},{7,8,9}};
    }
}

6.6.2 二维数组的内存布局(重要) 

二维数组的内存布局


http://www.kler.cn/a/564782.html

相关文章:

  • leetcode203-----移除链表元素
  • 基于Electron的应用程序安全测试基础 — 提取和分析.asar文件的案例研究
  • C#模式匹配详解
  • web前端初学Typescript由浅入深上手开发项目
  • 腾讯云大模型知识引擎×DeepSeek:如何搭建RAG促进文旅产业智能化升级
  • .Net 9下使用Tensorflow.net---DNN_Keras
  • 系统架构设计师考点——嵌入式技术
  • 常用的AI文本大语言模型汇总
  • Spring Boot问题总结
  • Flutter系列教程之(1)——环境配置、创建项目及打包apk
  • Imagination GPU 3D Graphics Wrokload
  • DeepSeek教unity------UI元素长按响应
  • Linux:目录创建命令mkdir功能及用法详解
  • 类和对象——拷贝对象时的一些编译器优化
  • 2025GDC 大会视角:服务器与 AI大模型算力发展的深度剖析
  • WordPress二次开发实现用户注册审核功能
  • 基于springboot网上农业农机设备在线租赁网站系统设计与实现
  • Moe(混合专家)架构和Dense架构对比?
  • Java 进阶笔记
  • Oracle 字符串分割革命:正则表达式与 Lateral Join 的优雅解法