Java基础知识(纯干货)
基础篇
IDEA 开发 Java项目
卸载JDK
删除Java的安装目录
删除JAVA_HOME
删除path下关于java的目录
java -version
安装JDK17
下载链接:https://download.oracle.com/java/17/archive/jdk-17.0.1_windows-x64_bin.exe
设置环境变量
- 在我的电脑->高级系统设置新建变量 JAVA_HOME,变量值为 E:\Java (此处填写自己的安装路径)
- 新建CLASSPATH 变量值为 %JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
- 在Path中新增变量 --- %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
- 测试是否安装成功 --- 在控制台输入 java 或者 java -version 不报错就可以了
安装JDK 8
百度搜索JDK8,找到下载地址
同意协议
下载对应版本
记住安装路径
配置环境变量
我的电脑-->右键-->属性-->高级系统设置
环境变量-->系统变量-->JAVA_HOME
配置Path变量----> %JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
测试是否安装成功
IDEA 代码快捷键
psvm 生成main方法
sout 输出 System.out.println(); 语句
Ctrl + D :复制当前行到下一行
alt + insert :会生成构造器(构造方法)
Ctrl + H :显示类结构图
快捷键 : Ctrl + ALT + T ---> 选择代码块进行包裹代码(如:if/else , try/catch......)
maven导依赖,浏览器直接搜 maven + mysql / standard 等等
Java语法
注释
单行注释: //
多行注释: /* 注释内容*/ , 可以注释一段文字
文档注释:(JavaDoc) /** 注释内容 */
标识符
标识符大小写敏感
应以字母、美元符、下划线开始
不可使用关键字作为变量名或方法名
数据类型
注意:
long 类型要在数字后面加个L
float类型要在数字后面加个F
String 用来定义字符串,String不是关键字
布尔型:
boolean flag = true; boolean flag = false;
什么是字节
位(bit):是计算机 内部数据 存储的最小单位,11001100是一个八位二进制数。
字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写B来表示。
字符:是指计算机中使用的字母、数字、字和符号
1 bit 表示1位 1Byte表示一个字节---> 1B(byte) = 8 bit
1024B=1KB 1024KB=1M 1024M=1G 1024G=1TB
数据类型扩展
字符扩展
//所有的字符本质还是数字
//编码 Unicode 表: (97 = a 65 = A) 2字节 0-65536 Excel 2的16次方 = 65536
//U0000 UFFFF
char c3 = '\u0061';
System.out.println(c3);
//转义字符 \t-->制表符 \n-->换行
System.out.println("Hello\nWorld!");
System.out.println("=================================================");
String sa = new String("hello world");
String sb = new String("hello world");
System.out.println(sa==sb); //false
String sc = "hello world";
String sd = "hello world";
System.out.println(sc==sd); //true
//对象 从内存分析
//布尔值扩展
boolean flag = true;
if (flag==true){ } //新手
if (flag){ } //老手
//Less is More! 代码要精简易读
类型转换
//强制转换 (类型)变量名 高--低
int i = 128;
byte b = (byte)i;
System.out.println(i); //128
System.out.println(b); // -128//自动转换 低--高
int m = 128;
double n = m;
System.out.println(m); //128
System.out.println(n); //128.0注意:
不能对布尔值进行转换
不能把对象类型转换为不相干的类型
在把高容量转换为低容量的时候,强制转换
转换的时候可能存在内存溢出,或者精度问题
char c = 'a';
int d = c+1;
System.out.println(d); // 98
System.out.println((char) d); // bpublic static void main(String[] args) {
//操作数比较大的时候,注意溢出问题
//JDK7新特性,数字之间可用下划线分割
int money = 10_0000_0000; int years = 20;
int total = money * years; // -1474836480 , 计算的时候溢出了
long total2 = money * years; //默认是int,转换之前已经存在问题
long total3 = money*((long)years); //先把一个数转换为 long
System.out.println(total3); //20000000000
}
变量
Java是一种强类型语言,每个变量都必须声明其类型。类型可以是基本类型,也可以是引用类型。
Java变量是程序中最基本的存储单元,其要素包括变量名、变量类型和作用域。
变量名必须是合法的标识符。
变量作用域
1. 类变量 2.实例变量 3.局部变量
public class Variable {
static int allClicks = 0; //类变量
String str = "Hello world"; //实例变量
public void method(){
int i = 0; //局部变量
}
}
变量使用---示例
public class Demo04 { //类变量 static
static double salary = 2500; //属性:变量 //实例变量:从属于对象; 如果不进行初始化,则输出该类型的默认值
//布尔值:默认是false
//除了基本类型,其余的默认值都是null
String name;
int age; //main方法
public static void main(String[] args) { //局部变量-->必须声明和初始化值
int i = 10;
System.out.println(i); //实例变量:对应上面的内容
//变量类型 变量名字 = new Demo04();
Demo04 demo04 = new Demo04();
System.out.println(demo04.age);
System.out.println(demo04.name); //类变量 static
System.out.println(salary);
}
//其他方法
public void add(){ }
}
变量的命名规范
类成员变量:首字母小写和驼峰原则:除了第一个单词以外,后面的单词首字母大写。如:monthSalary.
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线:MAX_VALUE
类名:首字母大写和驼峰原则:Man,GoodMan
方法名:首字母小写和驼峰原则:run(),runRun()
常量
常量名一般使用大写字符。
格式: final 常量名 = 值 ; 例: final double PI = 3.14 ;
修饰符(数据类型前的内容,如示例中的 static 和 final ),不存在先后顺序。
static final double PI = 3.14;
与final static double PI = 3.14;
输出内容相同。
运算符
数据类型没有 long 时,所有 非int 类型转为 int 型:
1 public static void main(String[] args) {
2 long a = 1234569653412L;
3 int b = 123;
4 short c = 10;
5 byte d = 8;
6 System.out.println(a+b+c+d); //结果为 Long 型
7 System.out.println(b+c+d); //结果为 Int 型
8 System.out.println(c+d); //结果为 Int 型
9 }
运算结果的数据类型为参与运算的变量中最高优先级的数据类型。
关系运算符返回的结果为:正确 / 错误 布尔值
幂运算
------借助Math类
//幂运算 2^3 2*2*2=8
double pow = Math.pow(2,3);
System.out.println(pow); // 8.0
位运算符
& | ^ ~
//位运算符
/** A = 0011 1100
* B = 0000 1101
* -------------------
* A&B = 0000 1100
* A|B = 0011 1101
* A^B = 0011 0001
* ~B = 1111 0010*
*/
<< 相当于 * >> 相当于 /
三元运算符
格式: x ? y : z 如果 x==true,则结果为 y,否则结果为 z
int score = 50;
String type = score < 60 ? "不及格":"及格";
System.out.println(type); // 结果为 不及格
运算符优先级
优先级 | 描述 | 运算符 |
---|---|---|
1 | 括号 | ()、[] |
2 | 正负号 | +、- |
3 | 自增自减,非 | ++、--、! |
4 | 乘除,取余 | *、/、% |
5 | 加减 | +、- |
6 | 移位运算 | <<、>>、>>> |
7 | 大小关系 | >、>=、<、<= |
8 | 相等关系 | ==、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | | |
12 | 逻辑与 | && |
13 | 逻辑或 | || |
14 | 条件运算 | ? : |
15 | 赋值运算 | =、+=、-=、*=、/=、%= |
16 | 位赋值运算 | &=、|=、<<=、>>=、>>>=、 |
字符串连接符 +
int m = 10;
int n = 20;
//字符串连接符 +
System.out.println(""+m+n); // 结果为 1020
System.out.println(m+n+""); // 结果为 30
JavaDoc生成文档
1. 在IDEA中生成一个Javadoc文档
首先新建一个文件夹,用于存放要生成的Javadoc文档;
点击 IDEA 顶部的Tools菜单,选择Generate JavaDoc选项;
然后在弹出界面,点击 Output directory 输入框后面的按钮,选择刚才新建的文件夹;
在底部的Locale输入框配置语言和编码集,语言用zh_CN,代表中文
-encoding utf-8 -charset utf-8
点击确定后,等待 IDEA 生成JavaDoc文档即可,
接下来打开JavaDoc文件夹,找到index.html文件,点击就能看到API文档。
2. 在IDEA中生成一个Javadoc文档
参见 https://blog.csdn.net/Joy_Roy6/article/details/123028798 (Ctrl+鼠标左键)
Java流程控制
Scanner对象
可以通过Scanner类来获取用户的输入。
基本语法:
Scanner s = new Scanner (System.in);
通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要使用 hasNext() 与hasNextLine() 判断是否还有输入的数据。
next() 与 nextLine() 的区别:
next方式:
1 public static void main(String[] args) {
2 //创建一个扫描器对象,用于接收键盘数据
3 Scanner scanner = new Scanner(System.in); //程序会等待用户输入完毕
4
5 System.out.println("使用next方式接收:"); //判断用户有没有输入字符串
6
7 if (scanner.hasNext()){
8 //使用next方式接收
9 String str = scanner.next();
10 System.out.println("输入的内容为:"+str);
11 }
12 //凡是属于IO流的类,如果不关闭,会一直占用资源
13 scanner.close();
14 }
也可以通过不使用 if() 判断,来获取用户输入的内容:
1 public static void main(String[] args) {
2 Scanner scanner = new Scanner(System.in);
3 System.out.println("请输入数据:");
4
5 String str = scanner.nextLine();
6 System.out.println("输出的内容为:"+str);
7
8 scanner.close();
9 }
小例子:
1 public static void main(String[] args) {
2 //输入多个数字,并求其总和与平均数,
3 //每输入一个数字用回车键确认,通过输入非数字来结束输入并输出执行结果
4 Scanner scanner = new Scanner(System.in);
5 //和
6 double sum = 0;
7 //计算输入了多少个数字
8 int m = 0;
9 //通过循环判断是否还有输入,并在里面对每一次进行求和与统计
10 while(scanner.hasNextDouble()){
11 double x = scanner.nextDouble();
12 m = m + 1;
13 sum = sum + x;
14 System.out.println("你输入了第"+m+"个数据,当前结果sum="+sum);
15 }
16 System.out.println(m + "个数的和为" + sum);
17 System.out.println(m + "个数的平均值是" + (sum / m));
18 scanner.close();
19 }
顺序结构
选择结构
1. if 选择结构
2. switch 多选择结构
Switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
Switch 语句中的变量类型可以是 byte, short, int 或char,String , 同时case 标签必须为字符串常量或字面量。
1 switch (){
2 case value :
3 //语句
4 break; //可选
5 case value :
6 //语句
7 break; //可选
8 //可以有任意数量的case语句
9 default : //可选
10 //语句
11 }
循环结构
1. while 循环
while 是最基本的循环,它的结构为:
while(布尔表达式){
//循环内容
}
只要布尔表达式为true,循环就会一直执行下去。
下面代码计算 1+2+3+...+100:
1 public static void main(String[] args) {
2 int i = 0;
3 int sum = 0;
4 while (i<=100){
5 sum = sum + i;
6 i++;
7 }
8 System.out.println(sum);
9 }
2. do...while 循环
do...while 循环和 while 循环相似,不同的是,do...while循环至少会执行一次。
do {
//代码语句
}while(布尔表达式);
下面代码计算 1+2+3+...+100:
1 public static void main(String[] args) {
2 int i = 0;
3 int sum = 0;
4 do {
5 sum = sum + i;
6 i++;
7 }while(i<=100);
8 System.out.println(sum);
9 }
3. For循环
for 循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
for 循环执行的次数是在执行前就确实的。
语法格式如下:
for (初始化;布尔表达式;更新){
//代码语句
}
练习:输出1-1000之间能被5整除的数,并且每行输出3个
1 public static void main(String[] args) {
2 for (int i = 0; i <= 1000; i++) {
3 if(i%5==0){
4 System.out.print(i+"\t");
5 } if (i%(5*3)==0){ //每行
6 System.out.println();
7 //System.out.println("\n");
8 }
9 }
10 }
练习:打印九九乘法表
//1.先打印第一列
//2.把固定的1再用一个循环包起来
//3.去掉重复项,i <= j
//4.调整样式
1 public static void main(String[] args) {
2 for (int j = 1; j <= 9; j++) {
3 for (int i = 1; i <= j; i++) {
4 System.out.print(j+"*"+i+"="+(j*i) + "\t");
5 }
6 System.out.println();
7 }
8 }
4.增强for循环
语法格式:
for(声明语句:表达式){
//代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
练习:遍历数组元素---以下为两种方法,法一为普通for循环,法二为增强for循环。
1 public static void main(String[] args) {
2 int [] numbers = {10,20,30,40,50}; //定义了一个数组
3
4 for (int i = 0; i < 5; i++) {
5 System.out.println(numbers[i]);
6 }
7 System.out.println("-----------------------------------------------------");
8 //遍历数组的元素
9 for(int x:numbers){
10 System.out.println(x);
11 }
12 }
break 与 continue
break 用于强行退出循环,不执行循环中剩余的语句。( break 语句也在switch 语句中使用)。
break 在任何循环语句的主体部分,均可用 break 控制循环的流程。
continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
流程控制练习
打印三角形
public static void main(String[] args) {
//打印三角形 5行
for (int i = 1; i <= 5; i++) {
for (int j = 5; 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();
}
}
Debug的使用
Java 方法详解
方法的定义
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段。
一般情况下,定义一个方法包含以下语法:方法包含一个方法头和一个方法体。
定义方法的格式:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
public class Demo01 {
//main方法
public static void main(String[] args) {
//实际参数:实际调用传递给他的参数
int sum = add(1, 2); //下面的add方法被static修饰时,main方法才可调用add()
System.out.println(sum); }
//加法
//形式参数,用来定义作用的
public static int add(int a,int b){
return a+b;
}
}
方法调用
调用方法:对象名.方法名(实参列表)
若是 static 即为静态方法,可以直接通过类名来调用;
举例:
若为非静态方法,先用 new 实例化该类,然后进行调用;
举例:
两种调用方法的方式:
当返回一个值的时候,方法调用通常被当作一个值。例如:
int larger = max(30, 40);
如果方法返回值是void,方法调用一定是一条语句。如:
System.out.println("Hello,World!");
方法的重载
定义:方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数类型或参数的个数。
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:
方法名称必须相同;
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等);
方法的返回类型可以相同,也可以不同;
仅仅返回类型不同不足以成为方法的重载。
可变参数
在方法声明中,在指定参数类型后加一个省略号(...)。
一个方法只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
1 public class Demo04 {
2 public static void main(String[] args) {
3 //调用可变参数的方法
4 printMax(34, 3, 3, 2, 66.6,68.68);
5 printMax(new double[]{1,2,3}); }
6 public static void printMax(double... numbers){
7 if(numbers.length == 0) {
8 System.out.println("No argument passed");
9 return;
10 }
11 double result = numbers[0];
12 //排序!
13 for (int i = 1;i < numbers.length; i++){
14 if(numbers[i] > result){
15 result = numbers[i];
16 }
17 }
18 System.out.println("The max value is " + result);
19 }
20 }
递归(笔试高频问点)
递归就是:A方法调用A方法,即自己调用自己。
递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
1 public class Demo06 {
2 //递归思想
3 //求阶乘 5! 5*4*3*2*1
4 public static void main(String[] args) {
5 System.out.println(f(5));
6 }
7 public static int f(int n){
8 if (n == 1){
9 return 1;
10 }else {
11 return n * f(n-1);
12 }
13 }
14 }
数组
数组的定义
数组是相同类型数据的有序集合。
相同类型的若干个数据,按照一定的先后次序排列组合而成。
每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
数组也是对象。数组元素相当于对象的成员变量。
数组长度是确定的,不可变得。如果越界,则报错:ArrayIndexOutOfBoundsException
数组的声明创建
首先必须声明数组变量,才能在程序中使用数组。
声明数组变量的语法如下:
dataType[] arrayRefVar;
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
数组的元素是通过索引访问的,数组索引从0开始。
获取数组长度:
arrays.length
1 public class ArrayDemo01 {
2 //变量的类型 变量的名字 = 变量的值
3 //数组类型
4 public static void main(String[] args) {
5 int[] nums; //1.声明一个数组
6 nums = new int[10]; //2.创建一个数组
7 //上面两句也可合并为一句:int[] nums2 = new int[10];
8 //3.给数组元素中赋值
9 nums[0] = 1; nums[1] = 2;
10 nums[2] = 3; nums[3] = 4;
11 nums[4] = 5; nums[5] = 6;
12 nums[6] = 7; nums[7] = 8;
13 nums[8] = 9; nums[9] = 10;
14 //计算所有元素的和
15 int sum = 0;
16 for (int i = 0; i < nums.length; i++) {
17 sum = sum + nums[i];
18 }
19 System.out.println("总和为:"+ sum);
20 }
21 }
数组的三种初始化
静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
动态初始化
int[] a = new int[2]; a[0]=1; a[1]=2;
数组的默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
1 public class ArrayDemo02 {
2 public static void main(String[] args) {
3 //静态初始化:创建 + 赋值
4 int[] a = {1,2,3,4,5,6,7,8};
5 System.out.println(a[0]);
6 //动态初始化:包含默认初始化
7 int[] b = new int[10];
8 b[0] = 10;
9 System.out.println(b[0]);
10 }
11 }
数组的使用
普通的for循环
For-Each循环
数组作方法入参
数组作返回值
1 public class ArrayDemo04 {
2 public static void main(String[] args) {
3 int[] arrays = {1,2,3,4,5};
4 //增强的for循环
5 //for (int array : arrays) {
6 // System.out.println(array);
7 //} printArray(arrays);
8 int[] reverse = reverse(arrays);
9 printArray(reverse);
10 }
11 //打印数组元素
12 public static void printArray(int[] arrays){
13 for (int i = 0; i < arrays.length; i++) {
14 System.out.println(arrays[i]+"");
15 }
16 }
17
18 //反转数组---即倒序输出数组元素
19 public static int[] reverse(int[] arrays){
20 int[] result = new int[arrays.length];
21 //反转的操作
22 for (int i = 0, j = result.length-1; i < arrays.length; i++,j--) {
23 result[j] = arrays[i];
24 }
25 return result;
26 }
27 }
多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其中每个元素都是一个一维数组。
二维数组
int a[][] = new int[3][5];
解析:以上二维数组a可以看成一个三行五列的数组。
1 public class ArrayDemo05 {
2 public static void main(String[] args) {
3 //[4][2]
4 int[][] array = {{1,2},{2,3},{3,4},{4,5}};
5 System.out.println(array[0][0]);
6 System.out.println(array[0][1]); // 1 2
7 System.out.println("================");
8 System.out.println(array.length); // 4
9 System.out.println(array[0].length); // 2
10 }
11 }
Arrays 类
数组的工具类 java.util.Arrays
Arrays 类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用
具有以下常用功能:
给数组赋值:通过 fill 方法
对数组排序:通过 sort 方法
比较数组:通过 equals 方法比较数组中元素值是否相等
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
可借助 JDK 帮助文档进行使用相关内容
1 public static void main(String[] args) {
2 int[] a = {1,2,3,4,9898,36523,498561,4512};
3 System.out.println(a);
4 //打印数组元素 Arrays.toString
5 Arrays.sort(a); //数组进行排序-升序
6 System.out.println(Arrays.toString(a));
7
8 Arrays.fill(a,2,4,0); //数组填充 此处2和4表示从第二位到第四位填充为0
9 System.out.println(Arrays.toString(a));
10 }
冒泡排序
冒泡排序代码:两层循环,外层冒泡轮数,里层依次比较。时间复杂度为O(n2)
1 public static void main(String[] args) {
2 int[] a = {5,158,45,6,89,68,12,39,56,45,53};
3 int[] sort = sort(a); //调用完自己写的排序方法以后,返回一个排序后的数组
4 System.out.println(Arrays.toString(sort));
5 }
6
7 //冒泡排序
8 //1. 比较数组中,两个相邻的元素,如果第一个数比第二个数大,就交换二者位置
9 public static int[] sort(int[] array){
10 //临时变量
11 int temp = 0;
12 //外层循环,判断要走多少次;
13 for (int i = 0; i < array.length-1; i++) {
14 boolean flag = false; //通过flag标识位减少无意义的比较
15 //内层循环,比较判断两个数,若第一个数比第二个数大,则交换位置
16 for (int j = 0; j < array.length-1-i; j++) {
17 if (array[j+1] < array[j]){
18 temp = array[j];
19 array[j] = array[j+1];
20 array[j+1] = temp;
21 flag = true;
22 }
23 }
24 if (flag == false){
25 break;
26 }
27 }
28 return array;
29 }
30 }
稀疏数组
当一个数组中大部分元素为0时,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
1 public class ArrayDemo08 {
2 public static void main(String[] args) {
3 //1. 创建一个二维数组 11*11 0:没有棋子 1:黑棋 2:白棋
4 int[][] array1 = new int[11][11];
5 array1[1][2] = 1; array1[2][3] = 2;
6 //输出原始数组
7 System.out.println("输出原始的数组");
8 for (int[] ints : array1) { //快捷方式: array1.for + 回车
9 for (int anInt : ints) { //快捷方式: ints.for + 回车
10 System.out.print(anInt+"\t");
11 }
12 System.out.println();
13 }
14 System.out.println("===================================");
15 //转换为稀疏数组保存
16 //获取有效值的个数
17 int sum = 0;
18 for (int i = 0; i < 11; i++) {
19 for (int j = 0; j < 11; j++) {
20 if (array1[i][j] != 0){ sum++; }
21 }
22 }
23 System.out.println("有效值的个数为:"+sum);
24 //2. 创建一个稀疏数组的数组
25 int[][] array2 = new int[sum+1][3];
26 array2[0][0] = 11; array2[0][1] = 11; array2[0][2] = sum;
27 //遍历二维数组,将非零的值,存放稀疏数组中
28 int count = 0;
29 for (int i = 0; i < array1.length; i++) {
30 for (int j = 0; j < array1[i].length; j++) {
31 if (array1[i][j] != 0){
32 count++;
33 array2[count][0] = i;
34 array2[count][1] = j;
35 array2[count][2] = array1[i][j];
36 }
37 }
38 }
39 //输出稀疏数组
40 System.out.println("稀疏数组:");
41 for (int i = 0; i < array2.length; i++) {
42 System.out.println(array2[i][0]+"\t"
43 +array2[i][1]+"\t"
44 +array2[i][2]+"\t");
45 }
46 System.out.println("===================================");
47 System.out.println("还原:");
48 //1. 读取稀疏数组的值
49 int[][] array3 = new int[array2[0][0]][array2[0][1]];
50 //2.给其中的元素还原它的值
51 for (int i = 1; i < array2.length; i++) {
52 array3[array2[i][0]][array2[i][1]] = array2[i][2];
53 }
54 //3. 打印
55 System.out.println("输出还原的数组");
56 for (int[] ints : array3) { //快捷方式: array1.for + 回车
57 for (int anInt : ints) { //快捷方式: ints.for + 回车
58 System.out.print(anInt+"\t");
59 }
60 System.out.println();
61 }
62 }
63 }
正式篇
面向对象编程
本质:以类的方式组织代码,以对象的组织(封装)数据。
三大特性:封装、继承、多态。
回顾方法及加深
方法的定义:
修饰符、返回值类型
break:跳出Switch,结束整个循环
return:结束方法,返回一个结果
方法名:注意规范,见名知意
参数列表:(参数类型,参数名)...定义可变常参数
异常抛出: 后面讲解
方法的调用:递归
静态方法
非静态方法
形参和实参
值传递和引用传递的区别:
this 关键字
创建与初始化对象
使用 new 关键字创建对象
使用 new 关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化以及对类中构造器的调用
一个类中就只有两部分:属性 和 方法
//类是抽象的,需要实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
构造方法(构造器)
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
并且构造器有以下两个特点:
必须和类的名字相同
必须没有返回类型/值,也不能写 void
作用:
使用 new 关键字,本质是在调用构造
构造器一般用来初始化值
快捷键: alt + insert 生成构造器(构造方法)
生成有参构造方法:alt + insert ---> constructor ---> 选择需要生成的 ---> OK
生成无参构造方法:alt + insert ---> constructor ---> 选择需要生成的 ---> select none
创建对象内存分析
参见 狂神视频 面向对象P65,即视频 面向对象06
简单小结类与对象
类与对象: 类是一个模板:抽象,对象是一个具体的实例
方法:定义、调用
对象的引用:
引用类型:基本类型(8种),对象是通过引用来操作的:栈--->堆
属性:字段(Field/成员变量)
默认初始化:数字: 0 0.0 char:u0000
boolean:false 引用:null
属性的定义: 修饰符 属性类型 属性名 = 属性值
对象的创建和使用
必须使用 new 关键字创造对象,创造对象还需要构造器
Person xiaoming = new Person();
对象的属性 xiaoming.name
对象的方法 xiaoming.sleep()
类:一个类中就只有两部分:属性 和 方法
静态的属性 即 属性
动态的行为 即 方法
封装
该露的露,该藏的藏
我们程序设计要追求 “高内聚,低耦合” 。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
属性私有,get / set
封装的意义:提高程序的安全性,保护数据; 隐藏代码的实现细节; 统一接口; 系统的可维护性增加了。
有时还需考虑数据的合理性,如下图。图中设置年龄不太符合实际,便在右侧Student类中的setAge里进行相应限制条件的设置:
继承
继承的本质是对某一批类的抽象,子类继承了父类,就会拥有父类的全部方法。
extends 意为 “扩展”。子类是父类的扩展。
Java中,类只有单继承,没有多继承!
继承是类与类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。
私有的东西无法被继承
Object 类
Java中,所有的类都默认直接或间接继承 Object 类。
super 关键字
super 调用父类的构造器,必须要在子类构造器的第一行。
注意点:
super 调用父类的构造方法,必须在构造方法的第一行;
super 必须只能出现在子类的方法或者构造方法中;
super 和 this 不能同时调用构造方法。
super 与 this 的区别:
代表的对象不同:
this :代表 本身调用者这个对象
super : 代表 父类对象的应用
前提 :
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法:
this( ):调用本类的构造
super( ):调用父类的构造
方法重写
重写都是方法的重写,和属性无关。
重写只跟非静态方法(成员方法)有关,而与静态方法无关;
静态方法和非静态方法是不一样的:
在静态方法中,方法的调用只和左边声明的对象类型有关,而与右边无关,是哪个类型,就调用对应的方法。
注意:重写需要有继承关系,子类重写父类的方法
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大,但不可以缩小: public > Protected > Default > private
抛出的异常:范围可以被缩小,但不能扩大:ClassNotFoundException --> Exception (大)
重写,子类的方法和父类必须要一致,但方法体不同。
为什么需要重写:
父类的功能,子类不一定需要,或者不一定满足。 Alt + Insert : @Override
多态
多态,即同一种方法可以根据发送对象的不同而采用多种不同的行为方式。
多态注意事项:
多态是方法的多态,属性没有多态
父类和子类,有联系 类型转换异常--->ClassCastException
存在的条件: ①有继承关系;②(子类重写父类方法)方法需要重写;
③父类引用指向子类对象---> Father f1 = new Son( );
不能重写的方法:
static 方法,属于类,不属于实例;
final 是常量;
private 方法,私有方法。
Application.java
1 package oop;
2 import oop.demo06.Person;
3 import oop.demo06.Student;
4
5 public class Application {
6 public static void main(String[] args) {
7 //一个对象的实际类型是确定的 // 可以指向的引用类型就不确定了
8 //Student 能调用的方法都是自己的,或者继承父类的
9 Student s1 = new Student();
10 //Person 是父类,可以指向子类,但是不能调用子类独有的方法
11 Person s2 = new Student(); //父类的引用指向子类
12 Object s3 = new Student();
13
14 //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
15 s2.run(); //子类重写了父类的方法,执行子类的方法
16 s1.run();
17 // s2.eat(); // s2前面是Person,但Person类里没有eat(),所以此处不能使用该句
18 }
19 }
Person.java
1 package oop.demo06;
2 public class Person {
3 public void run(){
4 System.out.println("run");
5 }
6 }
Student.java
1 package oop.demo06;
2 public class Student extends Person{
3 @Override
4 public void run() {
5 System.out.println("son");
6 }
7 public void eat(){
8 System.out.println("eat");
9 }
10 }
instanceof
instanceof 是 Java 的保留关键字。
它的作用是,测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
System.out.println( X instanceof Y);
能不能编译通过,取决于 X 与 Y 之间是否存在父子关系。
类型转换
1.
public static void main(String[] args) {
//类型之间的转化: 父 子 //高 ---> 低
Person obj = new Student();
//student 将这个对象转换为Student类型,
// 我们就可以使用Student类型的方法了
((Student)obj).go();
}
父类引用指向子类的对象
子转父,不可用子类特有方法,可获得子类重写父类的方法,可获得父类独有方法。
以下强制转换/自动转换不知道对否,待验证。
把子类转换为父类,由低到高,向上转型,自动转换
把父类转换为子类,向下转型:需要强制转换。 会丢失父类被子类所重写掉的方法。
父类转子类会丢失子类特有的一些方法
以上3、4点可以类比基本数据类型的转换:
double 转 int ,丢失小数;int 转 double ,强制转换
static 关键字详解
静态变量输出时,可以直接用 类名.变量名 来输出。
加了 static 可以不创建对象,而使用类名.属性名或者方法名 直接调用。只是在本类里可以省去类名。
静态变量对于类,所有对象(实例)所共享,当直接使用类去调用得到说明这个变量是静态的。
类的加载顺序:静态代码块 > 匿名代码块 > 构造方法
1 public class Person {
2 // 输出顺序:2 赋初值~
3 { //代码块(匿名代码块)
4 System.out.println("匿名代码块");
5 }
6 // 输出顺序:1 , static 只执行一次~
7 static{ //静态代码块
8 System.out.println("静态代码块");
9 }
10 // 输出顺序:3
11 public Person() {
12 System.out.println("构造方法");
13 }
14 public static void main(String[] args) {
15 Person person1 = new Person();
16 System.out.println("=============================");
17 Person person2 = new Person();
18 }
19 }
抽象类
abstract 修饰符可以用来修饰方法,也可以修饰类。
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
抽象类,不能使用 new 关键字类创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类继承的。
子类继承抽象类,就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
继承了抽象类的所有方法(包括抽象方法)的子类都必须要实现它的方法,除非子类也是抽象类。
Java中,类是单继承的,接口可以多继承。
抽象类特点:
不能new这个抽象类,只能靠子类去实现它:约束!
抽象类中可以写普通的方法
抽象方法必须在抽象类中
抽象类存在构造器吗?
抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。
在继承了抽象类的子类中通过super()或super(参数列表)调用抽象类中的构造方法。
接口
声明接口的关键词是 interface;
接口的作用:
约束
定义一些方法,让不同的人实现
接口中,所有定义的方法,其实都是抽象的 public abstract
public static final ~~ 属性其实都默认为常量,如 public static final int age;
接口不能被实例化,接口中没有构造方法
implements 可以实现多个接口;
必须要重写接口中的方法
内部类
内部类就是在一个类的内部再定义一个类。比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
内部类可以直接访问外部类方法和属性,不需要创建外部类的对象
一个Java类中可以有多个class类,但是只能有一个 public class 类
- 类型:成员内部类、静态内部类、局部内部类、匿名内部类
异常机制
检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略
Java把异常当做对象来处理,并定义一个基类 java.lang.Throwable 作为所有异常的超类。
在 Java API 中已经定义了许多异常类,这些异常类分为两大类,错误 ERROR 和 异常 Exception
Exception:
ERROR:
错误 ERROR :错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时也检查不到的。
2.
异常处理机制
异常处理五个关键字:try、catch、finally、throw、throws
快捷键 : Ctrl + ALT + T ---> 选择代码块进行包裹代码(如:if/else , try/catch......)
自定义异常
实际应用中的经验总结
Java基础知识(纯干货)的更多相关文章
- Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- 毕向东—Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- 黑马毕向东Java基础知识总结
Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记 侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- java基础知识小总结【转】
java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...
- Java基础知识系列——String
最近晚上没有什么事(主要是不加班有单身),就复习了一下Java的基础知识.我复习Java基础知识主要是依据Java API和The Java™ Tutorials. 今天是第一篇,复习了一下Strin ...
- 学习android学习必备的java基础知识--四大内部类
学习android必备的java基础知识--四大内部类 今天学习android课程,因为我的主专业是JAVA,但是兴趣班却有这其他专业的同学,学习android 需要具备一些java的基础知识,因此就 ...
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
- java基础知识梳理
java基础知识梳理 1 基本数据类型
- java基础知识回顾之---java String final类普通方法
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
随机推荐
- Linux - vim文件编辑器
vim 普通模式下 yy : 复制当前光标所在行 p : 粘贴 数字+yy :复制多行 dd :删除当前行 数字+dd :删除多行 u : 回滚 y$ : 光标到行结尾 y^ : 行开头到光标位置 y ...
- 四 APPIUM GUI讲解(Windows版)(转)
Windows版本的APPIUM GUI有以下图标或者按钮: ·Android Settings - Android设置按钮,所有和安卓设置的参数都在这个里面 ·General Settings – ...
- springboot整合nacos和dubbo
0. 源码 源码: gitee 1. 版本 java: 1.8.0_281 nacos: 2.1.2 2. 创建项目 创建一个简单的springboot或者maven项目, 或者代码库(gitee/g ...
- SpringBoot3集成Kafka
目录 一.简介 二.环境搭建 1.Kafka部署 2.Kafka测试 3.可视化工具 三.工程搭建 1.工程结构 2.依赖管理 3.配置文件 四.基础用法 1.消息生产 2.消息消费 五.参考源码 标 ...
- ORM查询一个表中有两个字段相同时,只获取某个值最大的一条
Table表如下: 获取表中name和hex值相同时age最大的那一条 ORM写法,两次查询 ids = table.values('name', 'age').annotate(id=Max('id ...
- TypeScript中Class基础使用
TypeScript是一种静态类型的JavaScript超集,它提供了许多增强的功能,其中之一就是对面向对象编程的支持.在TypeScript中,我们可以使用Class来定义类,这使得我们能够更加结构 ...
- Adobe全家桶PS、PR、AU等2022正版永久有效,无需破解直接安装就能用
[Adobe全家桶]已经亲测绝对好用,下载地址: 关注我的wx公众号"奋斗在IT"回复1013获取下载地址.
- GIT提交修改的项目到远程仓库
1.在项目目录下右键选择Git Bash. 2.执行提交命令三部曲 git add . //文件-暂存区,即将所有新增的文件添加到提交索引中,,add后面是"空格 点"就表示当前目 ...
- 海量前端后台Java源码模板下载
给大家收集了海量的模板和源码素材,可下载研究和学习使用. 一:前端响应式静态Html5+Css3网页模板(无后台) 1:PC模板:9900套响应式html5+css3网页 ...
- Jquery 将 JSON 列表的 某个属性值,添加到数组中,并判断一个值,在不在数据中
jquery 将 JSON 列表的 某个属性值,添加到数组中 如果你有一个JSON列表,并且想要将每个对象的某个属性值添加到数组中,你可以使用jQuery的$.each()函数来遍历JSON列表,并获 ...