Java基础笔记
标识符
-
-
首字母之后的字符可以是字母(A-Z或者a-z)、美元符号($)或者数字的任意字符组成;
-
标识符不能以java关键字命名;
-
变量名和方法名可以以中文命名,但不推荐使用;
数据类型
强语言类型
要求变量的使用要符合严格的规定,任何变量必须先申明后使用。
Java的数据类型分为两大类
-
基本数据类型
-
数值类型
-
整数类型:
-
byte占1个字节范围:-128-127
-
short占2个字节范围:-32768~32767
-
int占4个字节范围:-2147483648~2147483647
-
long占8个字节范围:-9223372036854775808~9223372036854775807
-
-
浮点类型:
-
float占4个字节
-
double占8个字节
-
-
字符类型:char占2个字节
-
-
布尔类型:boolean占一位,其值只能是true或false
-
-
引用数据类型
-
数组
-
类
-
接口
-
数据类型拓展
public class Demo01 {
public static void main(String[] args) {
//整数扩展 进制: 二进制(0b) 十进制 八进制(0) 十六进制(0x)
int i1 = 0b10;
int i2 = 10;
int i3 = 010;
int i4 = 0x10;
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
System.out.println(i4);
System.out.println("======================================");
/*======================================*/
//浮点数拓展 银行业务怎么表示钱?
//BigDecimal 数学工具类
/*======================================*/
//最好避免使用浮点数去比较(浮点数有舍入误差,只能约等于)
//最好避免使用浮点数去比较(浮点数有舍入误差,只能约等于)
//最好避免使用浮点数去比较(浮点数有舍入误差,只能约等于)
float f = 0.1f; //0.1
double d = 1 / 10; //0.1
System.out.println(f == d); //false
float f1 = 2132341232131123f;
float f2 = f1 + 1;
System.out.println(f1 == f2); //true
/*======================================*/
//字符拓展
/*======================================*/
System.out.println("======================================");
char c1 = 'a';
char c2 = '中';
System.out.println(c1);
System.out.println((int) c1); //强制转换
System.out.println(c2);
System.out.println((int) c2);//强制转换
//所有的字符本质都是数字(java的字符采用Unicode编码,占2个字节)
}
}
结果输出
2
10
8
16
======================================
false
true
======================================
a
97
中
20013
类型转换
-
由于Java语言属于强类型语言,运算的时候都会涉及到类型转换,转化规则如下
低------------------->高
byte,short,char—>int —> long —> float —> double
-
运算中,不同类型先转换成同种类型,然后再进行运算。
-
类型转换。
-
强制类型转化(由高容量转低容量)
-
自动类型转化(由低容量转高容量)
-
public class Demo02 {
public static void main(String[] args) {
/*
类型转换注意规则
1.不能对布尔类型进行转换;
2.高容量转低容量称为强制转换;
3.强制转换可能会造成内存溢出或精度丢失;
*/
int i = 128;
byte b = (byte) i; //强制转换(类型) 变量,此处造成内存溢出
System.out.println(i);
System.out.println(b);
//低容量转高容量会自动转换
System.out.println("==========================");
int i1 = 128;
double d = i1;
System.out.println(i1);
System.out.println(d);
//精度丢失
System.out.println("============================");
System.out.println((int) 12.1);
System.out.println((int) -452.41f);
//jdk7新特性,数字太长可以使用下划线分割
int money = 10_0000_0000;
System.out.println(money);
}
}
结果输出
128
-128
==========================
128
128.0
============================
12
-452
1000000000
变量
什么是变量?
顾名思义,就是可以变化的量。
变量的作用域
-
类变量(又称静态变量,属于类,类的所有对象共用)
-
实例变量(不赋值,则初始化值为0,属于对象)
-
局部变量(方法内部有效)
public class Demo03 {
static int i1 = 1; //类变量
/*
1.实例变量如果不进行初始化,默认值为0;
2.布尔类型的默认值为false;
3.除了基本数据类型,其他类型默认为null;
*/
int i2; //实例变量
//常量,变量前面加final
static final int i3 = 3;
public static void main(String[] args) {
int i4 = 4; //局部变量
System.out.println(i1);
Demo03 demo03 = new Demo03();
System.out.println(demo03.i2);
System.out.println(i3);
System.out.println(i4);
}
}
结果输出
1
0
3
4
变量命名规范
-
要求所有的变量名、方法名、类名见名知意;
-
命名规范尽量使用驼峰式命名法;
-
单个单词的变量名和方法名使用小写,若存在多个单词,则首字母小写,其余后面每个单词首字母大写(mySalary,getMoney());
-
类名要求每个单词的首字母大写(class Hello{});
-
常量要求单词全部大写,单词之间用下划线分离(MAX_VALUE);
运算符
-
算数运算符:+ , - , * , / , % , ++ , --
-
赋值运算符:=
-
关系运算符:> , < , >= , <= , == , != , instanceof
-
逻辑运算符:&& , ||, !
-
位运算符:& , | , ^ , ~ , >> , << , >>>(了解)
-
条件运算符:? :
-
扩展运算符:+= , -= , *= , /=
重点
-
++(自增)、--(自减)
package oprate;
public class Demo01 {
public static void main(String[] args) {
/*
++(自增)、--(自减)运算符
1.++在前,先加后用
2.++在后,先用后加
*/
int a = 1;
int b = a ++; //a在之后才执行自增
//a = a + 1;
//a = a + 1;
int c = ++ a; //a在之前进行了自增
System.out.println(a); //3
System.out.println(b); //1
System.out.println(c); //3
}
}
输出
3
1
3
-
位运算符
package oprate;
public class Demo02 {
public static void main(String[] args) {
/*
A = 0011 1100
B = 0000 1101
A & B = 0000 1100 (按位与:同1则为1,其余是0)
A | B = 0011 1101 (按位或:只要有一个1则为1,其余为0)
A ^ B = 0011 0001 (亦或:相同为0,不同为1)
~A = (取反:1100 0011)
*/
//面试题:怎么样用2得到16最快
//位运算效率极高
//<< 左移,相当于*2
//>> 右移,相当于/2
//0000 0010 2
//0000 0100 4
//0000 1000 8
//0001 0000 16
System.out.println(2<<3);
}
}
输出结果
16
Java流程控制
Scannel对象的使用
package oprate;
import java.util.Scanner;
public class Demo03 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入,使用next接收:");
while (scanner.hasNext()) {
String next = scanner.next();
System.out.println(next);
}
//关闭资源
scanner.close();
}
}
输出
请输入,使用next接收:
hello world
hello
world
事例:在控制台输入多个数字,要求求和和平均数
import java.util.Scanner;
public class Demo04 {
public static void main(String[] args) {
//在控制台输入多个数字,要求求和和平均数
Scanner scanner = new Scanner(System.in);
double sum = 0; //和
int count = 0; //输入的个数
while (scanner.hasNextDouble()){
double in = scanner.nextDouble();
sum += in;
count ++;
}
System.out.println("总和为:" + sum);
System.out.println("平均数为:" + (sum / count));
}
}
结果输出
2
4
5
6
8
x
总和为:25.0
平均数为:5.0
for循环的使用
使用for循环打印出三角形
public class Demo05 {
public static void main(String[] args) {
//使用*打印出三角形
for (int i = 1; i <= 7; i++) {
for (int j = 7; j > i; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
for (int j = 1; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
输出结果
*
***
*****
*******
*********
***********
*************
Java方法
-
什么是方法的重载
-
方法名必须相同;
-
参数列表必须不相同(参数个数不同、参数类型不同或参数顺序不同);
-
方法返回值可以相同也可以不同;
-
仅仅返回值类型不同不足以造成方法的重载
递归
递归方法包括两部分
-
递归头:什么时候不需要调用自身方法。如果没有头,将陷入死循环。
-
递归体: 什么时候需要调用自身方法。
例:使用递归求5!(5的阶层),5 * 4 * 3 *2 * 1
public class Demo01 {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
//使用递归求5的阶层
System.out.println(demo01.f(5));
}
public int f(int n){
if(n == 1)
return 1;
else
return n * f(n - 1);
}
}
输出结果
120
数组
对数组进行反转
public class Demo01 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println("数组反转前输出:");
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
System.out.println("数组反转后:");
int[] newArr = reverse(arr);
for (int n : newArr) {
System.out.print(n + " ");
}
}
static int[] reverse(int[] arr){
int[] newArr = new int[arr.length];
for (int i = 0, j = arr.length - 1; j >= 0; i++, j--) {
newArr[i] = arr[j];
}
return newArr;
}
}
输出结果:
数组反转前输出:
1 2 3 4 5 6
数组反转后:
6 5 4 3 2 1
冒泡排序
import java.util.Arrays;
public class Demo02 {
public static void main(String[] args) {
//冒泡排序(由小到大)
int[] arr = {6,3,7,9,12,4,8,32,13};
System.out.println("排序前输出:" + Arrays.toString(arr));
System.out.println("排序后输出:" + Arrays.toString(sort(arr)));
}
static int[] sort(int[] arr){
//临时变量
int temp = 0;
//外层循环,需要走多少次
for (int i = 0; i < arr.length - 1; i++) {
//内层循坏,两两比较,如果第一个数比第二个数大,则交换位置
for (int j = 0; j < arr.length - 1 - i; j ++){
if(arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
}
结果输出:
排序前输出:[6, 3, 7, 9, 12, 4, 8, 32, 13]
排序后输出:[3, 4, 6, 7, 8, 9, 12, 13, 32]
面向对象编程(OOP)
-
面向对象编程的本质:以类的方式组织代码,以对象的组织封装数据。
-
面向对象的三大特性:
-
封装
-
继承
-
多态
-
方法参数的传递:
-
在Java中只存在值传递;
-
基本数据类型的参数传递,本质是拷贝了传递的变量的值;
-
引用类型的传递,本质是拷贝了对象的引用,也就是对象的地址;
基本数据类型传递代码事例:
package array;
public class Demo03 {
public static void main(String[] args) {
//基本数据类型的参数传递
int a = 1;
System.out.println(a);//1
//调用方法
change(a);
System.out.println(a); //1
}
static void change(int a){
a = 10;
}
}
输出结果:
1
1
引用类型传递代码事例:
package array;
public class Demo04 {
public static void main(String[] args) {
//引用类型的参数传递
Student student = new Student();
System.out.println(student.name);//null
change(student);
System.out.println(student.name);//张三
}
static void change(Student student){
student.name = "张三";
}
}
class Student{
String name;
}
输出结果:
null
张三
类与对象的关系
-
类是抽象的概念,对象是具体的实例;
-
把具有同种特性抽取出来就成了一类,类更像是一块模板,而对象是根据这块模板创造出来的一个具体实例;
-
例如:人类是一种类,每个人都有眼睛、嘴巴、鼻子...我们把这些具有相同特征的人统称为人类,而像小明、小红就是人类的一个具体对象;
构造方法注意点
-
创建对象的时候都会调用这个对象的构造方法;
-
在不手动添加构造方法的时候,每个类都会有一个无参的构造方法;
-
构造方法必须与类名一致;
-
构造方法没有返回值,但也不能用void修饰;
-
如果手动加一个有参构造器,好像使用无参构造器,那必须手动添加一个无参构造器;
-
new一个对象的本质是调用对象的构造器;
-
new一个子类对象的时候,子类的构造器会调用父类的构造器(super(),默认第一行且隐藏);
方法的重写
注意:
-
重写的方法名和参数列表必须相同;
-
重写方法的修饰符范围只能扩大,不能缩小,例如:父类的方法是public,子类要重写此方法,修饰符就只能是public;
-
抛出的异常范围可以被缩小,不能扩大(理解:继承过来的只能越来越好,不能越来越差);
-
方法的重写针对的是非静态方法的重写;
多态
注意点:
实现多态有三个前提:
-
必须存在继承关系;
-
必须有对方法的重写;
-
必须是父类引用指向子类对象;
Java代码执行顺序
静态代码块、匿名代码块、构造器,事例:
package com.zq.oop;
class Person {
public Person() {
System.out.println("执行Person构造函数");
}
//一般用来赋初始值
{
System.out.println("执行匿名代码块");
}
//只执行一次
static {
System.out.println("执行静态代码块");
}
}
public class Demo01 {
public static void main(String[] args) {
new Person();
System.out.println("=============================");
new Person();
}
}
结果输出:
执行静态代码块
执行匿名代码块
执行Person构造函数
=============================
执行匿名代码块
执行Person构造函数
内部类
-
成员内部类
package com.zq.innerclass;
/**
* 实例内部类
*/
public class Demo01 {
public static void main(String[] args) {
//new一个内部类对象,必须先new一个外部类对象,通过外部类new出内部类
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.test();
}
}
class Outer{
private int id = 1;
class Inner{
void test(){
//实例内部类能访问外部类的成员变量
System.out.println(id);
}
}
}
-
静态内部类
package com.zq.innerclass;
/**
* 静态内部类
*/
public class Demo02 {
public static void main(String[] args) {
//new一个静态内部类对象,无须new一个外部类对象
Outer02.Inner inner = new Outer02.Inner();
inner.test();
}
}
class Outer02{
private int id = 1;
static class Inner{
void test(){
//静态内部类不能访问外部类的成员变量
System.out.println("hello world");
}
}
}
-
局部内部类
package com.zq.innerclass;
/**
* 局部内部类
*/
public class Demo03 {
public static void main(String[] args) {
//通过创建外部类的实例,调用方法即可;
Outer03 outer03 = new Outer03();
outer03.inner();
}
}
class Outer03{
private int id = 1;
public void inner(){
class Inner{
int id = 2;
void test(){
System.out.println(id);
}
}
Inner inner = new Inner();
inner.test();
}
}
-
匿名内部类
package com.zq.innerclass;
/**
* 匿名内部类
*/
public class Demo04 {
public static void main(String[] args) {
//匿名内部类的创建
new Outer04().test();
}
}
class Outer04{
private int id = 1;
public void test(){
System.out.println(id);
}
}
异常处理机制
-
Exception
-
检查性异常:是指程序员在编写代码时,代码编写错误或有问题,编译时这些错误是不能忽略的。
-
运行时异常:运行时异常可能被程序员避免的异常,与检查性异常相反,在程序编译时可以被忽略掉。
-
Error:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如:当栈溢出时,就会发生错误,错误的发生,编译是无法检测到的。
异常的处理
-
Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
-
异常类分为两大类,分别为Error和Exception。
处理异常的关键字有:
try、catch、finally、throw、throws
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用