Java 基础学习笔记
1、编译型和解释型
编译型:compile:将中文翻译成英文。
解释型:如js,边解释边执行。
Java是先编译,再在操作系统进行解释,编译型和解释型相结合的。
2、java语法
2.1 注释:单行注释,多行注释,文档注释。
2.2 标识符:标识符都是以字母、数字、美元符、下划线组合,且不能以数字开头,不能以关键字命名。
3、数据类型
java是一种强类型语言,要求变量的使用严格符合规定,所有的变量必须先定义后才能使用。
Java的数据类型分为两大类:基本类型,引用类型。
//Long类型要在数字后面加个L,用于区分它是长整型。浮点型同理。
long num2 = 30L;
float num3 = 20.2F;
double num4 = 3.14159;
int类型的包装类Integer。
什么是字节:
4、数据类型扩展
//===========================
//浮点数扩展 银行业务怎么表示?钱
//BigDecimal 数学工具类
//===========================
//总结:float 有限,离散,舍入误差,大约,接近但不等于
//double
//最好完全避免使用浮点数进行比较
float f = 0.1f; //0.1
double d = 1.0/10; //0.1
System.out.println(f==d);//false
float f1 = 12312321312123f;
float f2 = f1 + 1;
System.out.println(f1==f2);//true
总结:对小数进行比较或者加减,最好使用BigDecimal工具类对小数进行定义。
//===========================
//字符扩展
//===========================
char c1 = 'a';
char c2 = '中';
System.out.println(c1);//a
System.out.println((int)c1);//97
System.out.println(c2);//中
System.out.println((int)c2);//20013
//所有的字符本质还是数字
//转移字符
// \t 制表符
// \n 换行
5、类型转换
低 -------------------->高
byte,short,char-> int -> long -> float -> double
//强制转换 (类型)变量名 高--低
//自动转换 低--高
注意点:
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转换到低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题(如byte最大值为127,若定义为128,则会存在内存溢出。小数强转为整数则会出现精度问题)
6、变量与常量
变量作用域:
类变量(写在类里面的,static关键词修饰的)、实例变量(也是写在类里面的,但是没有static关键词修饰)、局部变量(写在方法里面的)
局部变量:必须声明和初始化值,不然不能使用。
实例变量:从属于对象;如果不自行初始化,
基本类型的默认值为0或0.0。布尔值默认是false,除了基本类型,其余的默认值是null。
Variable variable = new Variable ();
System.out.println(variable.str);// 能够输出hello world,这就是实例变量定义的作用。
常量:
//修饰符,不存在先后顺序,final static也可以。
static final double pi = 3.14;
常量命名一般都是大写字母和下划线组合。如MAX_VALUE;
7、运算符
关系运算符:instanceof 判断一个对象是否是一个类的实例。
a++ ,++a
逻辑运算符:
与:&& //逻辑与运算,两个变量都为真,结果才为真
或:|| //逻辑或运算,两个变量有一个为真,则结果为真
非! //逻辑非运算,如果为真,则结果为假,如果是假则结果为真
位运算:
/*
A = 0011 1100
B = 0000 1101
---------------
A&B = 0000 1100 A或B
A|B = 0011 1101 A与B
A^B = 0011 0001 A异或B
~B = 1111 0010 非B
思考题:2*8 = 16 用什么办法可以运算最快?
可以用移位运算符,因为移位运算符是跟底层二进制打交道的,效率极高。
例如,2<<3 翻译出来就是 2 * 2^3 = 2*8,
3<<2 翻译出来就是 3*2^2 = 3*4;
<< 左移是乘
>> 右移是除
*/
字符串拼接符:
int a = 10;
int b = 20;
//字符串连接符 + ,String
System.out.println(""+a+b);//结果为1020
System.out.println(a+b+"");//结果为30
//总结:如果拼接的字符串在后面,则前面的变量会进行运算
8、包机制
一般利用公司域名倒置作为包名
com.公司名.项目名.模块名.*
9、JavaDoc生成文档
参数信息:
@author 作者名
@version 版本号
@since 指明需要最早使用的jdk版本
@param 参数名
@return 返回值情况
@throws 异常抛出信息
如何使用Idea生成JavaDoc文档?
10、Scanner交互
public static void main(String[] args) {
//创建一个扫描对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
//判断用户有没有输入字符串
/*if(scanner.hasNext()){
//使用next方式接收
String str = scanner.next();
System.out.println("我输入了:" + str);
}
//凡是属于IO流的类,如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();*/
/*System.out.println("使用nextLine方式接收:");
//判断是否还有输入
if(scanner.hasNextLine()){
String str = scanner.nextLine();
System.out.println("我输入了:" + str);
}
scanner.close();*/
System.out.println("请输入数据:");
String str = scanner.nextLine();
System.out.println("输出的内容为:"+str);
scanner.close();
}
11、流程控制结构
顺序结构、选择结构、循环结构
if多选择结构:只会进入满足条件的表达式,然后就跳出了
一旦其中一个else if 语句检测为true,其他的else if 以及 else 语句都将跳过执行。
switch多选择结构:
循环结构:
while 循环、do....while循环、增强for循环
for循环结构:
//初始化//条件判断//迭代
for(int i = 1;i < 100;i++){
}
循环结构小练习:
//练习1:计算0到100之间的奇数和偶数的和
int oddSum = 0;//保存奇数的和
int evenSum = 0;//保存偶数的和
for (int i = 0; i < 100; i++) {
if(i%2!=0){
oddSum+=i;
}else{
evenSum+=i;
}
}
System.out.println("奇数的和:"+oddSum);
System.out.println("偶数的和:"+evenSum);
//练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
int m=0;//用于计数
for (int i = 0; i < 1000; i++) {
if(i%5==0){
System.out.print(i + "\t");
m++;
if (m%3==0){
System.out.println();//换行符
}
}
}
//练习3:打印九九乘法表
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j+"*"+i+"="+i*j);
System.out.print("\t");
}
System.out.println();
}
普通for循环和增强for循环结构的区别:
int[] numbers = {10,20,30,40,50};
//普通for循环
for (int i=0; i < numbers.length; i++){
System.out.println(numbers[i]);
}
System.out.println("===============");
//增强for循环 遍历数组元素
for (int number:numbers){
System.out.println(number);
}
总结:可以简化代码
break和continue的区别:
break用于强行退出循环,不执行循环中剩余的语句。
continue用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
12、Java的方法
一个方法只完成一个功能,保证方法的原子性,有利于日后的扩展。
Java都是值传递,不是引用传递。
方法的重载:
重载就是在一个类中,有相同的方法名称,但形参不同的方法。
方法的重写:子类继承父类,并重写父类的方法。
可变长参数:
在方法声明中,在指定参数类型后加一个省略号(...)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo05 {
public static void main(String[] args) {
Demo05 demo05 = new Demo05();
demo05.test(1,2,3,4,5);
}
public void test(int a,int... i ){
System.out.println(i[0]);//会输出2,也就是定义的i的参数可以随便变化的
}
}
13、递归讲解
递归就是自身调用自身方法,递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
递归要有边界条件:边界
返回阶段:如n*(n-1)
Java的运行就像一个栈,main方法在最底层,每递归一个方法都会网上加一层,所以递归次数多了,程序就很容易崩溃。所以尽量少用递归。
14、数组
数组是相同类型数据的有序集合。
数组的声明:int[] nums; int nums[];
数组的四个基本特点:
1、数组的长度是确定的,数组一旦被创建,它的大小就是不可以改变的。
2、其元素必须是相同类型,不允许出现混合类型。
3、数组中的元素可以是任何数据类型,包括基本类型和引用类型。
4、数组变量属引用类型,数组本身就是对象,每个元素相当于该对象的成员变量,Java中对象是在堆中的,所以数组无论保存声明类型,数组对象本身是在堆中的。
数组的三种初始化:
1、静态初始化:
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)}//引用初始化
2、动态初始化:
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
3、数组的默认初始化:
数组是引用类型,它的元素相当于雷打实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
数组特点小结:
- 数组是相同对象数据类型的有序集合
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度是确定的,不可变的。如果越界,则报ArrayIndexOutoBounds错误。
小作业,将数组逆序输出:
package main.java;
public class Demo07 {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5};
int[] reverse = reverse(nums);//将数组逆序
printArray(reverse);//打印逆序后的数组
}
//将数组元素逆序
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
for (int i = 0,j = arrays.length -1; i < arrays.length; i++,j--) {
result[j] = arrays[i];
}
return result;
}
//输出打印数组
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
}
15、内存分析
16、多维数组
多维数组就是数组嵌套数组。
package main.java;
public class Demo08 {
public static void main(String[] args) {
//可以看成一个4行2列的数组。
int[][] array = {{1,2},{3,4},{5,6},{7,8}};
printArray(array[0]);//{1,2}
System.out.println();
System.out.println(array[2][0]);//5
System.out.println(array[3][1]);//8
System.out.println(array.length);//4
System.out.println(array[0].length);//2
}
//输出打印数组
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
}
17、Arrays类
Java工具类的一种,常用方法:
给数组赋值:通过fill方法。
对数组排序:通过sort方法,按升序。
比较数组:通过equals方法比较数组中元素值是否相等。
将数组转转换成字符串:通过toString方法。
查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
18、冒泡排序
两两比较,最大的一个数比较到最后一个去,然后最后一个不动,比较剩余的数。依次循环比较。
package main.java;
import java.util.Random;
//冒泡排序
public class Demo09 {
public static void main(String[] args) {
int[] arr = new int[5];//声明一个数组
Random r = new Random();//生成随机数
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(20);//生成10以内的随机数放入数组中
}
boolean flag = false;//通过flag标识位减少没有意义的比较
for (int j = arr.length -1; j > 0; j--) {
for (int i = 0; i < j; i++){
if (arr[i] > arr[i+1]){
swap(arr,i,i+1);
flag = true;//数组没有处在最好的情况(正序),则继续循环
}
}
if(!flag){//如果数组是排好的,则可以跳出循环
break;
}
}
printArrays(arr);
}
//打印数组元素
static void printArrays(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
//将数组元素进行交换
static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
19、稀疏数组
概念:记录有效的坐标,记录出原始数值的坐标及有效值,记录每个值的有效坐标。
待更新代码。
20、面向对象
1、Java的核心思想就是OOP(面向对象编程)
2、面向过程思想:步骤清晰简单,第一步做什么,第二步做什么...
面向对象思想:物以类聚,分类的思维模式。
面向过程适合处理一些较为简单的问题,面向对象适合处理复杂的问题。
3、面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模板。
21、构造器详解
1、一个类即使什么都不写,它也会存在一个方法,这个方法就是构造方法。
2、构造器核心概念:
2.1、有参构造:一旦定义了有参构造,无参构造就必须显示定义。
//一个类即使什么都不写,也会存在一个隐式的无参的构造方法。
public class Person{
String name;
//无参构造,定义了有参构造,无参构造就必须要给定义出来
//作用:1.使用new关键字,本质是在调用构造器 2.用来初始化值
public Person(){
}
//有参构造,可以根据传递的参数来创建对象包含的属性
public Person(String name){
this.name = name;//this. 代表当前类
}
}
3、总结:
构造器:
1、构造器和类名相同
2、没有返回值
作用:
1、new本质是在调用构造方法。
2、初始化对象的值。
注意点:定义有参构造之后,如果想使用无参构造,就需要显式的定义一个无参的构造器。
22、对象内存分析
解析:Java的主方法和定义的对象的变量名都是存放在栈中的,每执行一个方法也在在栈中叠加。还有一个堆都是存放实例化出来的对象的,方法区放置一些静态方法和常量,也属于堆。
23、封装、继承、多态
1、封装:
追求高内聚,低耦合。
从代码层面解释:高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
高内聚就是说相关度比较高的部分尽可能的集中,不要分散。
低耦合就是说两个相关的模块尽可以能把依赖的部分降低到最小,不要让两个系统产生强依赖。模块与模块之间关联小,相互独立。
封装的意义:
//属性私有,get/set
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.增加系统的可维护性
2、继承:
子类继承父类,实际就是子类(派生类)对父类(基类)的扩展。
Java只能单继承,没有多继承。一个儿子只能有一个爸爸。
1.子类继承了父类,就会拥有父类的全部方法。
2.Java中所有类都直接或间接继承Object类。
如果类被final修饰了,则不能被继承了。
3、多态:
多态即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
多态注意事项:
1、多态是方法的多态,属性没有多态
2、父类和子类,有联系 类型转换异常:ClassCastException
3、多态存在的条件:有继承关系,子类重写父类方法,父类引用指向子类对象。Father f1 = new Son();
注意:多态是方法的多态,属性没有多态性。
注意点:
1、private,static,final修饰的方法不能被重写。
24、Super详解
super注意点:
1.super调用父类的构造方法,必须在构造方法的第一个
2.super必须只能出现在子类的方法或构造方法中。
3.super和this不能同时调用构造方法。
super 和 this的不同:
代表的对象不同:
this:本身调用者的这个对象。
super:代表父类对象的应用。
前提:
this:没有继承也能使用
super:只能在继承条件才可以使用
构造方法:
this()本类的构造
super()父类的构造
25、方法重写
重写:需要有继承关系,子类重写父类的方法。
1、方法名必须相同
2、参数列表必须相同
3、修饰符:范围可以扩大但不能缩小; public>protected>default>private
4、抛出的异常:范围可以被缩小,但不能被扩大。
重写,子类的方法和父类的方法必须要一致,方法体不同。
为什么需要重写?
1、父类的功能,子类不一定需要,或者不一定满足。
26、instanceof和类型转换
X instanceof Y 如果X和Y有继承关系,则返回true。
27、static关键字详解
static可以修饰变量,方法,还有代码块。
跟随类一起加载。
只执行一次。
28、抽象类与接口
抽象类:
1、抽象类只能单继承,接口可以多继承。
2、不能new一个抽象类,只能靠子类去实现它。
3、抽象类 中可以写普通的方法。抽象方法必须写在抽象类中。
接口:
作用:
1.约束 2.定义一些方法,让不同的人实现。
3.public abstract 4.public static final定义常量
5.接口不能被实例化,接口中没有构造方法。
6.implements可以实现多个接口。
7.必须要重写接口中的方法。
29、内部类
30、异常
异常处理处理五个关键字:try,catch,finally,throw(在方法中抛出异常),throws(在方法上抛出异常);···
try{//try监控区域
}catch(Exception e){//catch 捕获异常
}finally{//处理善后操作
}
finally 可以不要,但是如果是IO流,资源必须关闭。
catch(想要捕获的异常类型,如 Throwable,Exception)
假设要捕获多个异常,要从小到大去捕获。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具