Java学习笔记
JAVA基础
内容倾向作者自身的理解和学习过程
一、注释,关键字,字符等小知识
- 注释(略)
- 关键字——关键字的字母全部小写,一般他它们也有特殊颜色标记。
例:class:用于创建一个类,是java最基本的组成单元。
public class HelloWorld{
//其中HelloWorld就是类的名字,即“类名”。
}
- 特殊字符
制表符——可将前面的字符补齐到8(有利于数据如表格般对齐) - 变量——变量可暂时存储数据以及修改。
如:int、double…- 变量可参与计算
- 变量值可修改
- 变量只能存储一个值
- 变量在使用前必须赋值
- 变量的计算使用
public class test{
public static void main(String[] args){
int count = 0;
count +=1;
System.out.println(count);
}
} - 进制
二进制:0b开头
十进制:不加前缀
八进制:0开头
十六进制:0x开头 - 颜色数据
- 黑白:0和1表示
- 灰度:0和1~255表示
- 彩色:由三原色组成,红绿蓝,简称rgb,即三个0~255范围内的数形成一个颜色。也可以用其他进制表示。
- 声音数据
由对声音采样的波形图表示声音,由数字表示波形中每个点的位置。
二、基础概念
1. 基本数据类型
- 整数:byte,short,int,long (写入数据后末尾需要加上L)
long num1 = 123L
- 浮点数:float (数据值末尾需加上F),double
float num2 = 12.3F
- 字符:char
- 布尔:boolean
2.标识符——给类、方法、变量等起的名字(见名知意)
1.硬性要求
- 由数字、字母、下划线(_)和美元符($)组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
2.软性要求
- 方法、变量名
- 标识符是一个单词时全部小写.
name
- 标识符由多个单词组成时,第一个单词首字母小写,其余单词首字母大写。
fristName
- 类名
- 标识符是一个单词时全部大写.
Student
- 标识符由多个单词组成时,每个单词首字母大写.
GoodStudent
3.键盘录入
Scanner——这个类可以接收键盘输入的数字
- 导包——Scanner这个类的位置
import java.util.Scanner;//放在类定义的上面
- 创建对象
Scanner sc = new Scanner(System.in);// 只有sc是变量名,可变,其他的都不允许变
// 这里相当于打个招呼表示我开始用Scanner包了,只需要写一次
- 接收数据
int i = sc.nextInt();// 除了i,其他的都不允许变
Test
import java.util.Scanner;
public class Exercise{
public stasic void main(String[] args){
//创建对象
Scanner sc = new Scanner(System,in);
System.out.println(“Please enter the first number.”);
//接收数据
int number1 = sc.nextInt();
System.out.println(“Please enter the first number.”);
int number2 = sc.nextInt();
System.out println("number1 +number2);
}
}
4.idea的使用
-
项目结构
-
project(项目)
-
module(模块)
-
package(包)
-
class(类)
(文件名和类名保持一致,修改命名时右键类rename即可)
-
-
新建使用步骤
- new project(创建新的项目)
- Empty project(一个空项目)
- project Structure(创建模块)
- modules——New module——java
- src——new——package(创建包,公司域名的反写+作用)
- com.school.test1(指创建了一个多级包,com里school里test1)
- 右键要写入的包,创建New Java Class(新建一个类)
-
快捷
- psvm(public stasic void main)
- sout(System.out.println)
- CTRL SHIFT F10(运行,输出语句和输出内容都会在控制台展示)
- 后续内容中还会学到
- 生成变量快捷键 ctrl alt v
- 按住鼠标滚轮可以上下多选
5.运算符和表达式
-
运算符(eg:+、++i、i++、/(除法)、%(取余))
对字面量或变量进行操作的符号- 代码中小数运算结果有可能是不精确的。
-
表达式(eg:a+b)
运算符将变量连接起来,符合java语法的式子。
不同运算符连接表达式体现的是不同类型的表达式 -
算术运算符
- 数值拆分
公式:
个位:数值%10
十位:数值/10%10
百位:数值/100%10
千位:数值/1000%10
… - 数据类型转换 (数据类型不一样,则不能运算)
- 隐式转换(默认有小数参与,结果为小数,byte short char会直接提升为Int后再运算)
- 强制转换(eg:int a = 300;byte b = (byte) a;//数据若大于取值范围,可能发生错误)
Test
1.System.out.println(1+2+“abc”+2+1)//“3abc21”
//当出现字符串时,后面进行的就是拼接操作
2.System.out.println(1 + ‘a’);//98,a的ascII码表值为97
3.System.out.println(‘a’ + “abc”);//有字符串参与,就是拼接操作- 自增自减运算符
总结:
- 单独写时在前还是在后结果是一样的。
- a++参与计算则先使用a计算,后给a+1,即先用后加。
- ++a参与计算则先给a+1,后进行计算,即先加后用
- 赋值运算符——略
————————————————————
循环语句选择语句学计算机唯一最通俗易懂的,这里跳过跳过
- 数值拆分
Test
- 判断是否为回文数
- 使用知识点:循环有次数选for,无次数选while
public stasic void main(string[] args){
int x =1234;
int temp = x;//定义一个临时变量用于记录x原来的值,用于最后进行比较
int num = 0;
while(x!=0){
int ge = x % 10;
x = x / 10;
num = num + ge;//解决了得到倒过来的x的问题
}
}
- 求商和余数(要求不使用乘除法和%运算符)
6.数组
- 输出数组长度
System.out.println(arr.length)
- 遍历的时候也可以直接使用length
for(int i = 0;i < arr.length;i++)
//遍历的便捷方式:fori、变量名.fori - 输出遍历的元素之和
for(int i = 0;i < arr.length;i++){
sum =sum +arr[i];
} - 数组中能被3整除的有多少个
for(int i = 0;i < arr.length;i++){
if(arr[i] % 3 == 0){
count++;
}
}
//一个循环尽量只做一个事情
- 数组动态初始化
- 初始化只指定数组长度,由系统分配初值.不明确具体数值时推荐使用动态初始化
int[] arr = new int[3];
- 内存分配
- 栈
方法运行时使用的内存,如main方法运行时会进入方法栈中运行。开始运行时会进栈,执行完毕会出栈。 - 堆
new所创建的东西都存储在堆内存中。包括省略了new所创造的数组 会在堆内存中开辟空间并产生地址。开辟的各个空间之间相互独立。

图中arr[0]便是通过arr找到了右边的堆空间,再通过零索引找到第一个数据。 - 两个数组指向同一空间的内存图
相当于第二个数组没有在堆中创建新的空间,只是指向了堆中第一个数组的空间。此时空间中的值若发生改变,其他数组访问的也将是修改之后的结果。
- 栈
int[] arr1 = {11,22};
int[] arr2 = arr1;
test
- 求数组中的最大值
int [] arr ={33,5,22,44,55};
int max =arr[0];//初始化值利用数组中的值
for(int i = 0; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
system.out.println(max);
} - 将十个1~100之间的随机数存入数组
int[] arr = new int[10];
Random r = new Random();
for(int i = 0; i < arr.length; i++){
int number = r.nextInt(bound:100)+1;
//100指0~99之间,则需要加1
arr[i]=number
}
for(int i = 0; i < arr.length; i++){
system.out.println(arr[i]);
}
//再加上一个条件,将数组中的数据实现头尾交换,及顺序颠倒过来
for(int i = 0,j = arr.; i < arr.length; i++) - 将数组中的数随机打乱并输出
import java.util.Random;
import java.util.Scanner;
public class Class_1 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
Random r = new Random();
for (int i = 0; i < arr.length; i++) {
int randomIndex = r.nextInt(arr.length);//Index为随即索引
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = temp;//进行了随机数与数组内每个数的交换
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
7.方法
-
方法(method)是程序中最小的执行单元。
public stasic void main(String[] args){
//主方法内容
} -
将一个方法放在一个包,需要使用时直接调用,便会方便许多,也提高了方法的复用性,可维护性(例如植物大战僵尸里植物发射的炮弹速度相同,其发射速度代码也就相同,则可以将速度代码打包,分别每个植物设计时在发射速度这块直接调用速度包即可。也可以说是有点类似C里面的函数)
-
方法与调用的定义
- 方法定义后不会直接运行,需要手动调用才能执行
- 方法格式1:
public static void 方法名( 驼峰式命名 ){
方法体(即打包的代码);
}
例如:
public static void playGame(){
打印语句;
}- 调用格式1:
方法名();
例如:
playGame();//方法必须先定义后调用- 简单练习:
//人肉计算器:定义一个方法,在方法内部定义两个变量,求出它们的和并打印。
package …;
public class Test{
public static void main(String[] args){
getSum();
}
public static void getSum(){
int sum1 = 10;
int sum2 = 20;
int result = num1 + num2;
System.out.println(result);
}
}- 方法格式2(带参数):
public static void method(int num1, int num2){
int result = num1 + num2 ;
System.out.println(result);
}- 调用格式2(带参数):
方法名(参数);
例如:
method(10,2o);
//或者
method(变量1,变量2);- 举例:
public class MethodDemo02 {
public static void main(String[] args) {
getSum(10,20);//实参
int a = 10;
int b = 10;
getSum(a,b);//实参
}
public static void getSum(int num1,nt num2) {//形参
int result = num1 + num2;
System.out.println(result);
}
} -
形参与实参
- 形参:全称形式参数,是指方法定义中的参数
- 实参:全称实际参数,方法调用中的参数
- 形参与实参调用时要一一对应
-
方法定义技巧
- 我要干什么————方法体
- 需要什么来完成————形参
- 练习
//练习1
package test;
public class Test1 {
public static void main(String[] args) {
//需求:定义一个方法,求长方形的周长,将结果在方法中进行打印。
//目标:根据不同的需求,选择定义无参的方法,还是带参数的方法
getLength( 5.2, 1.3);
}
//1. 我要干嘛? 求长方形的周长
//2. 我干这件事情,需要什么才能完成? 长宽
public static void getLength(double len, double width){//=.方法
double result = (len + width) * 2;
System.out.println(result);
}
}
//练习2
package test;
public class Test1 {
public static void main(String[] args) {
//需求:定义一个方法,求圆的面积,将结果在方法中进行打印。
//目标:根据不同的需求,选择定义无参的方法,还是带参数的方法
getArea(1.5);
}
public static void getArea(double radius){//=.方法
double result = radius * radius * 3.14;
System.out.println(result);
}
} -
带返回值的方法的定义和调用
调用处拿到方法结果后,才能根据结果进行下一步操作。- 定义格式:
public static 返回值类型 方法名(参数){
方法体;
return 返回值;
}
//示例
public static int getSum(int a,int b){
int c = a + b;
return c;
}- 调用格式
//直接调用:
方法名(实参);//一般用于无返回值的
//赋值调用:
整数类型 变量名=方法名(实参);//用于有返回值的,返回给新定义的变量名
//输出调用:
System.out.println(方法名(实参));- 什么时候使用有返回值的方法
在调用处要根据方法的结果,去编写另一段代码。 - 方法中的返回值的意义
方法的返回值是方法执行结果的一种表现形式。- 比如方法是c=a+b,调用了后得到的c的结果便是这个方法在调用位置处显示的结果。
这里的 调用就变成了单纯的计算后的c的值。 - 如果方法中没有返回值,属于void,那么在调用后就只能单纯在输出界面展示。
并不能将调用得到的值拿来使用。 - 通俗来讲, 返回值,就是让调用的结果成为一个能继续使用的变量
- 比如方法是c=a+b,调用了后得到的c的结果便是这个方法在调用位置处显示的结果。
- 注意事项
- 带返回值的方法在需要 重复性 时使用!
- 方法之间是平级关系,不能相互嵌套定义
-
方法的重载
- 自我理解:为了使多个类似的方法命名时更加简单
便使用重载,令 方法名一样,但方法的形参不同 - 简单记:同一个类中,方法名相同,参数不同的方法,与返回值无关
- 参数不同:个数不同,类型不同,顺序不同
- 简单练习
package bao;
import java.util.Random;
import java.util.Scanner;
public class Class_1 {
public static void main(String[] args) {
compare(2, 4);
compare((byte)2,(byte)4);//难以区分时类型强制转换即可。
//还可以通过赋值的方式也可以,比如:byte a1=2;byte a2=4;compare(a1,a2);
//但此时只能调用
compare((long)2,(long)4);
compare((double)2, (double)4);
}
public static void compare(int a1, int a2) {
System.out.println(“int”);
System.out.println(a1 == a2);
}
public static void compare(byte a1, byte a2) {
System.out.println(“byte”);
System.out.println(a1 == a2);
}
public static void compare(long a1, long a2) {
System.out.println(“long”);
System.out.println(a1 == a2);
}
public static void compare(double a1, double a2) {
System.out.println(“double”);
System.out.println(a1 == a2);
}
} - 自我理解:为了使多个类似的方法命名时更加简单
-
方法练习:
//1. 设计一个方法用于遍历数组
public class Main_1 {
public static void main(String[] args) {
//1.定义数组
int[] arr = {11, 22, 33, 44, 55};
//2.调用方法遍历数组
printArr(arr);
}
//定义方法用于遍历数组
// 方法的调用处不需要继续使用结果,所以不需要返回值,使用void
public static void printArr(int[] arr)
{
System.out.print(“[”);
for (int i = 0; i < arr.length; i++)
{
if (i == arr.length - 1)
{
System.out.print(arr[i]);
} else
{
System.out.print(arr[i] + “,”);
}
}
System.out.println(“]”);
}
}
//2. 设计一个方法求数组的最大值,并将最大值返回
public class Main_1 {
public static void main(String[] args) {
//1.定义一个数组
int[]arr = {10,4,6,2,7};
//2.调用方法求最大值
int max = getMax(arr);
//3.打印
System.out.println(max);
}
//要返回值
public static int getMax(int[]arr){
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
}
//3. 定义一个方法判断数组中的某一个数是否存在,将结果返回给调用处。
public class Main_2 {
public static void main(String[] args) {
//1.定义数组
int[] arr = {11,33,55,77,22,11};
//2.判断一个数字是否在数组中存在
boolean flag = contains(arr,189);
System.out.println(flag);
}
//3.结果返回true或false
public static boolean contains(int []arr,int number){
for (int i = 0; i < arr.length; i++) {
if(arr[i] == number){
return true;
//为什么不用break,因为break是跟结束循环和switch有关的。
//return跟方法有关,表示1结束方法,2返回结果。
//如果方法执行到了return,那么整个方法全部结束,里面的循环也随之结束了。
}
}
//判定不存在
return false;
}
}
//4.定义一个方法copyOfRange(int[]arr,int from,int to)
//功能:将数组arr中索引from(包含from)开始。到索引to结束(不包含to)的元素复制到新数组中,将新数组返回。
package Class_11;
public class Main_3 {
public static void main(String[] args) {
//1.定义原始数组
int[]arr = {1,2,3,4,5,6,7,8,9};
//2.调用方法拷贝数据
int[] copyArr = copyOfRange(arr, 3, 7);
//3.遍历copyArr
for (int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
}
//将数组arr中索引from(包含from)开始。
//到索引to结束(不包含to)的元素复制到新数组中
public static int[] copyOfRange(int[]arr,int from,int to){
//int[]表明返回的是一个数组
//1.定义数组
//静态:直到所有元素。动态:知道要存几个元素,不知道具体
int[]newArr = new int[to - from];//动态数组
// 2.把原始数组arr中的from到to上对应的元素,直接拷贝到newArr中
//伪造索引的思想
int index = 0;
for (int i = from; i < to; i++) {
//arr[i];赋值到数组中
newArr[index] = arr[i];
index++;
}
return newArr;
}
}
//运行结果:4,5,6,7 -
方法的内存
- 方法调用的基本内存原理
( 栈:方法运行时使用的内存,方法进栈运行, 运行完毕就出栈。符合先进后出原则)
( 堆:new出来的,都在内存中开辟了一个小空间) - 基本和引用数据类型
- 基本数据类型:变量中存储的是真实的数据
- 引用数据类型(new出来的):变量中存储的是数据的地址值,引用了其他空间的数据
-
int[]arr1 = {1,2,3};
int[]arr2 = arr1;
//赋值给其他变量,赋的地址值
- 方法传递基本数据类型的内存原理
调用无返回值的方法,会导致方法内的值发生改变,调用结束后便出栈,从而不会改变main方法中的值。(即形参改变,不影响实参的值)所以想要改变实参,就必须要有return来返回值。 - 方法传递引用数据类型的内存原理
传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值。(使两个数组指向同一个地址,所以改变了其中一个的形参,另一个也会受影响,因为都传递的是地址值)
- 方法调用的基本内存原理
8.面向对象
- 设计对象并使用
- 类和对象
- 类:相当于设计图,是对象共同特征的描述,我将其理解为制造具体各种东西的工厂。
- 对象:是真实存在的具体东西。
(所以在java中必须先设计类才能获得对象) - 定义一个类:
public class 类名{
1.成员变量(代表属性,一般是名词)
2.成员方法(代表行为,一般是动词)
3.构造器
4.代码块
5.内部类
}
//比如:
public class phone{
//属性(成员变量)
String brand;
double price;
//行为(方法)
public void call(){
}
public void playGame(){
}
}- 得到类的对象
类名 对象名 = new类名();
Phone p = newPhone(); - 使用对象
访问属性:对象名.成员变量
访问行为:对象名.方法名(…)
- 类的几个补充注意事项
- 用来描述一类事物的类,专业叫做:javabean类。
在javabean类中,是不写main方法的。 - 在之前,编写main方法的类,叫做测试类。
我们可以在测试类中创建javabean类的对象并进行赋值调用。 - 类名首字母大写,需见名知意,驼峰模式。
- 一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。
实际开发中建议还是一个文件定义一个class类。 - 成员变量的完整定义格式是:
修饰符 数据类型 变量名称 = 初始化值;
一般无需定义初始化值,存在默认值。初始化一般在使用类来得到具体的对象使进行。
- 用来描述一类事物的类,专业叫做:javabean类。
- 类和对象
- 封装
-
- 什么是封装?
- 告诉我们,如何正确设计对象的属性和方法。
- 原则:对象代表什么,就得到封装对应的数据,并提供数据对应的行为
- 注意:主函数中创建对象去调用类时,对象名要用对应所使用类的名称,命名一致才能调用!!
-
- 封装思想
- 让编程变得简单,不用记对象有哪些方法,有什么事再找对象,调方法就行。
-
- private关键字:
- 权限修饰符,可修饰成员变量和成员方法。修饰过的成员只能再本类中才能当问。
- 针对每个私有化成员变量,都需要提供get(对外提供成员变量的值)方法,set(给成员变量赋值)方法。
作用:给成员变量进行赋值的,但不需要告诉用户返回值,所以用void。
-
- 成员变量和局部变量
-
- 就近原则
- System.out.println(age);// // 输出局部变量 age
- System.out.println(this.age);// 输出成员变量 age
-
- this的作用?
- 可以区别成员变量和局部变量
-
- this的本质
- 哪个对象调用了方法,this 就代表哪个对象。
-
- 构造方法
- 概述:构造方法也叫构造器或构造函数。
- 作用:在创建对象的时候给成员变量进行赋值的。
- 格式:
public class Student{
修饰符 类名(参数){
方法体;
}
} - 格式特点:
- 方法名与类名相同,大小写也要一致。
- 没有返回值类型,连void都没有
- 没有具体的返回值(不能由return带回结果数据)
- 执行时机:
- 创建对象时由虚拟机调用,不能手动调用构造方法
- 每创建一次对象,就会调用一次构造方法。
- 构造方法的定义
- 如果没有定义构造方法,系统将给出一个默认的无参构造方法
- 如果定义了构造方法,系统将不再提供默认的构造方法
- 构造方法的重载
- 带参的构造方法,和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载
- 推荐的使用方式
- 无论是否使用,都手动书写无参构造方法,和带全部参数的构造方法
- 注意事项
- 定义了有参构造器,就没有无参构造器了,便需要自行写。
所以建议在任何时候都手动写上空参和带全部参数的构造方法。
- 定义了有参构造器,就没有无参构造器了,便需要自行写。
- 标准JavaBean
- 格式
- 类名需要见名知意
- 成员变量使用 private 修饰
- 提供至少两个构造方法
- 无参构造方法
- 带全部参数的构造方法
- 成员方法
- 提供每一个成员变量对应的 get和set
- 如果还有其他行为也需要写上
- 构造法快捷键:
alt + insert
alt + Fn + insert
- 格式
- 对象内存分布
- s.name中的s是指的地址,name则是s地址指向的值
- s.study()中s指的是成员方法study的地址,整个便指s地址所指向的study方法。
- this的内存原理
- this的作用:区分局部变量和成员变量
- this的本质:所在方法调用者的地址值
- 成员与局部
- 成员变量:类中方法外的变量
- 局部变量:方法中的变量
9.字符串
-
String(引用数据类型)
- 直接赋值
String name = " ";
- new构造方法:
- 根据字符数组创建字符串对象
- 根据字节数组创建字符串对象
(相同内容也会开辟新空间,比较浪费内存,尽量用第一种方式)
- java内存模型:
public class StringDemo{
public static void main(String[] args){
String s1 = “abc”;
String s2 = “abc”;
}
}
当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。
不存在:创建新的
存在:复用
- 字符串的比较
- 基本数据类型:比较的是数据值
- 引用数据类型:比较的是 地址值
- 比较字符串对象中的内容是否相等
- 比较字符串对象中的内容是否相等,忽略大小写
package bao;
public class Ex_12 {
public static void main(String[] args) {
//1.创建两个字符串对象
String s1 = new String(“abc”);
String s2 = “Abc”;
//2.==号比较
//基本数据类型比的是数据值
//引用数据类型比较的是地址值
System.out.println(s1 == s2);//false
//3.比较字符串对象中的内容是否相等
boolean result1 = s1.equals(s2);
System.out.println(result1);
//4.比较字符串对象中的内容是否相等,忽略大小写
boolean result2 = s1.equalsIgnoreCase(s2);
System.out.println(result2);//true
}
}
- 注意:键盘录入abc和代码中定义的字符串abc用==比较也不相等。 因为键盘录入是new出来的,导致地址值不同
- 遍历字符串
- public char charAt(int index):根据索引返回字符
- public int length():返回此字符串的长度
- 数组的长度:数组名.length
- 字符串的长度:字符串对象.length()
ArrayList 集合
- ArrayList成员方法
- 增:boolean add(E e)——添加元素,返回值表示是否添加成功
- 删:boolean remove(E e)——删除指定元素,返回值表示是否删除成功
- E remove(int index)——删除指定索引的元素,返回被删除元素
- 改:E set(int index,E e)——修改指定索引下的元素,返回原来的元素
- 查:E get(int index)——获取指定索引的元素
- int size()——集合的长度,也就是集合中元素的个数
- 基本数据类型对应的包装类

如ArrayList list = new ArrayList<>();
应该写成
ArrayList list = new ArrayList<>(); - 练习

static 静态变量(共享的使用static)
- 静态变量——被static修饰的成员变量
- 被该类所有对象共享
- 静态变量不属于对象,属于类
- 静态变量是随着类的加载而加载的,优先于对象出现的
(也可以理解为静态变量是类的属性而不是实例的属性) - 可以用类名调用(更推荐)或对象名调用
- 静态方法——被static修饰的成员方法
- 多用在测试类和工具类中
- javabean类中很少会用
- 类名调用(更推荐)或对象名调用
- 三种类
- javabean类——用来描述一类事物的类
- 测试类——用来检查其他类是否书写正确,带有main方法的类,是程序的入口
- 工具类——帮我们做一些事情,但不描述任何事物的类
- 类名需要见名知意
- 私有化构造方法
- 方法定义为静态的(方便调用)
未完待续







