1.java准备
1.安装jdk
1.搜索jdk:https://www.oracle.com/java/technologies/downloads/#java8
2.双击安装
3.记住安装路径:
4.配置环境变量:
系统变量:
JAVA_HOME: E:\java\jdk1.8
pyth:%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
测试:
cmd;
java -version
关于命令行javac 和javadoc无法使用时解决办法:
在用户变量中添加jdk的bin目录
2.hello world
1.随便创建一个文件夹存放代码
2.新建一个java文件
- 文件后缀名为:.java
- Hello.java
3.编写代码
public class Hello{
public static void main (String[] args){
System.out.print(“Hello World!”);
}
}
4.编译javac java文件,会生成一个class文件
5.运行class文件,java class文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BOTwPEvq-1647240968122)(E:\java闭关修炼\note\学习笔记\image-20220119230753651.png)]
3.java程序运行机制
编译型
解释型
2.java基础
1.注释
单行注释://这是一个单行注释
多行注释:/* 注释 */
文档注释:
2.标识符和关键字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6yo53s8W-1647240968123)(1.java基础.assets/image-20220120111344509-16426484556281.png)]
3.数据类型
**强类型语言:**要求变量的使用严格符合规定,所有变量都必须先定义后才能使用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aKLffbkZ-1647240968125)(1.java基础.assets/image-20220120112532556-16426491465052.png)]
1.八大基本数据类型
//整数数据类型
byte num1 = 127;
short num2 = 32767;
int num3 = 10;
long num4 = 10L; // long类型要在数字后面加个L
//小数:浮点类型
float num5 = 50.1F; //float要在数字后面加个f
double num6 = 3.141592653589793238462643;
//字符
char name7 ='国';
//字符串,String不是关键字,是类
// String name = "董方龙"
//布尔值:
boolean flag = false;
//boolean flag = true;
2.引用类型
类;接口;数组
3.数据类型拓展
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i1 = 10;
int i2 = 010; //八进制0
int i3 = 0x10; //十六进制0x
System.out.println(i1); 10
System.out.println(i2); 8
System.out.println(i3); 16
System.out.println("=====================================");
//=========================================================
//浮点数拓展? 银行业务怎么表示? 钱
// BigDecimal 数字工具类
//=========================================================
//float 有限 离散 舍入误差 大约 接近但不等于
//double
//最好完全避免使用浮点数进行比较
//最好完全避免使用浮点数进行比较
//最好完全避免使用浮点数进行比较
//=========================================================
//字符拓展?
//=========================================================
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
}
```编码 Unicode 2字节 0 -- 65536
所有的字符本质还是数字 董:33891 方:26041 龙:40857
```java
char c3 = '\u0061';
System.out.println(c3); // 输出a
//转义字符
// \t 制表符
// \n 换行
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
//对象 从内存分析
4.类型转换
java是强类型语言
低-------------------------------------------->高
byte,short,char–>int->long->float->double
运算中,不同类型的数据先转为同一类型,然后进行运算
注意点:
1.不能对布尔值进行转换;
2.不能把对象类型转化为不相干的类型;
3.在把高容量转换为低容量的时候,强制转换
4.转化的时候可能存在内存溢出,或者精度的问题
System.out.println((int)23.7f); //23
System.out.println((int)-45.89f); //-45
System.out.println("=======================");
char c = 'a';
int d = c+1;
System.out.println(d); //输出98
System.out.println((char) d); //输出b
System.out.println("===========================");
//操作数比较大的时候,注意溢出问题
//JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money * years; //输出-1474836480
System.out.println(total);
long total2 = money * years; //默认是int,转换之前已经存在问题了
long total3 = money * ((long)years);
System.out.println(total2); //输出-1474836480
System.out.println(total3); //输出20000000000
4.变量,常量,作用域
变量作用域
- 类变量:
- 实例变量:
- 局部变量:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rh3JOM7h-1647240968128)(1.java基础.assets/image-20220121113444068-16427361007871.png)]
//类变量 static
static double salary = 2500;
//常量final
//修饰符不存在先后顺序
static final double PI = 3.14;
//属性:变量
//实例变量:从属于对象;如果不进行初始化,这个类型的默认值 0 0.0
//布尔值:默认是false
//除了基本类型,其余的默认值都是null
String name;
int age;
//main方法
public static void main(String[] args) {
//局部变量:必须声明和初始化值
int i = 10;
System.out.println(i);
//变量类型:
Demo03 demo03 = new Demo03();
System.out.println(demo03.age); //0
System.out.println(demo03.name); //输出null
//类变量 static
System.out.println(salary); //输出2500.0
System.out.println("=======================================");
//常量
System.out.println(PI);
5.基本运算符
算术运算符:+ , - , * , / , % , ++ , –
赋值运算符: =
关系运算符:> , < , >= , <= , == , != instanceof
逻辑运算符:&& , || , !
位运算符:& , | , ^ , >> , << , >>>
条件运算符:? :
拓展赋值运算符: += , -= , *= , /=
```java
System.out.println(""+a+b); //输出1020
System.out.println(a+b+""); //输出30
```java
int a = 10;
int b = 20;
int c = 21;
//int d = 25;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/(double)b);
System.out.println(c%a);
long q =1234567890L;
int w = 123;
short e = 10;
byte r = 8;
System.out.println(q+w+e+r); //Long
System.out.println(w+e+r); //Int
System.out.println(e+r); //Int
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
System.out.println(a!=b);
6.包机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhEO9SHO-1647240968130)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220121160740490-16427524795332.png)]
7.JavaDoc
javadoc命令是用来生成自己API文档的
参数信息
@author 作者名
@version版本号
@since指明需要昨早使用的jdk版本
@param 参数名
@return返回值情况
@throws异常抛出情况
3.流程控制
1.用户交互scanner
java.until.Scanner
scanner对象:scanner对象获取用户输入
**基本语法:**Scanner s = new Scanner(System.in);
通过Scanner类的next()与nextLine方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据
next():
1.一定要读取到有效字符后才可以结束输入
2.对输入的有效字符之遇到的空白,next()会自动将其去掉
3.只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
4.next不能得到带有空格的字符串
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if (scanner.hasNext()){
//使用next方式接收
String str = scanner.next();
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成良好习惯用完就关掉
scanner.close();
}
nextLine():
1.以Enter未结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符
2.可以获得空白
public class Demo02 {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接收:");
//判断用户有没有输入字符串
if (scanner.hasNextLine()) {
//使用next方式接收
String str = scanner.nextLine();
System.out.println("输出的内容为:" + str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成良好习惯用完就关掉
scanner.close();
}
}
2.Scanner进阶使用
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//从键盘接收数据
int i = 0;
float f = 0.0f;
System.out.println("请输入整数:");
if(scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据:"+i);
}else{
System.out.println("你输入的不是整数数据!");
}
System.out.println("请输入小数:");
if (scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+f);
}else{
System.out.println("输入的不是小数数据!");
}
}
public static void main(String[] args) {
//我们可以输入多个数字 ,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果
Scanner scanner = new Scanner(System.in);
//和
double sum = 0;
//计算输入了多少个数字
int m = 0;
//通过循环判断是否还有输入,并在里面对每一次进行求和和统计
System.out.println("请输入整数:");
while (scanner.hasNextDouble()){
double x = scanner.nextDouble();
m = m + 1;
sum = sum + x;
System.out.println("你输入了第"+m+"个数据,当前结果是sum="+sum);
}
System.out.println(m+"个数的和为"+sum);
System.out.println(m+"个数的平均值是" + (sum / m));
scanner.close();
}
3.顺序结构
4.选择结构
1.if单选结构
2.if双选结构
3.if多选择结构:
if
else if
else if
else
4.switch多选择结构
反编译
5.循环结构
1.while循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIBBHWR1-1647240968134)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220123143909495-16429199535341.png)]
public static void main(String[] args) {
//计算1+2+3+4+...+100=?
int i = 0;
int sum = 0;
while (i<=100){
sum = sum + i;
i++;
}
System.out.println(sum);
}
2.do…while循环
3.for循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxRUdSaU-1647240968136)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220125141641546-16430914070241.png)]
九九乘法表:
public class ForDemo04 {
public static void main(String[] args) {
for (int j = 1; j <= 9; j++) {
for (int i = 1; i <= j; i++) {
System.out.print(i+"*"+j+"="+(i*j)+"\t");
}
System.out.println();
}
}
}
增强for循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Xi6RWs3-1647240968140)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220128220223727-16433785466021.png)]
public class ForDemo05 {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50}; //定义了一个数组
for (int i = 0; i < 5; i++) {
System.out.println(numbers[i]);
}
System.out.println("====================");
//遍历数组元素
for (int x: numbers){
System.out.println(x);
}
}
}
4.Java方法
1.何谓方法
- java方法是语句的集合,他们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他的地方被引用
**设计方法的原则:**方法的本意是功能块,就是实现某个功能的语句块的集合。原子性
一个方法
2.方法的定义及调用
1.类似乎一个函数,完成特定功能的代码片段
2.方法包含一个方法头和方法体。下面是一个方法的所有组成部分:
- **修饰符:**修饰符这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- **返回值类型:**方法可能会返回值。returnValueType是方法返回值的数据类型。没有返回值,returnValueType是关键字void
- **方法名:**是方法的实际名称。方法名和参数表共同构成方法签名。
- **参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的。方法可以不包含任何参数。(实参-----形式参数)
- **方法体:**包含具体的语句,定义该方法的功能
值传递和引用传递
3.方法重载
重载就是在一个类中,有相同的函数名,但形参不同的函数
方法的重载的规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回类型可以相同可以不相同
- 仅仅返回类型不同不足以成为方法的重载
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
4.命令行传参
有时候你希望运行一个程序时候再传递给它消息。这就要靠传递命令行参数给main()函数实现。
public class Demo03 {
public static void main(String[] args) {
//args.length 数组长度
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i+"]:"+args[i]);
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvWSTpRf-1647240968142)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220204230226732-16439869494321.png)]
5.可变参数
- java支持传递同类型的可变参数给一个方法
- 在方法生命中,在指定参数类型后加一个省略号(…)
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo05 {
public static void main(String[] args) {
//调用可变参数的方法
printMax(34,3,3,2,56.5);
printMax(new double[]{1,2,3});
}
public static void printMax(double... numbers){
if (numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序!
for (int i = 1; i < numbers.length; i++) {
if (numbers[i]> result){
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uneOJxRJ-1647240968143)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220205234158621-16440757206511.png)]
6.递归
A方法调用B方法,我们很容易理解!
递归就是:A方法调用A方法!就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力于用有限的语句来定义对象的无限集合。
递
归
结
构
包
括
两
个
部
分
:
\textcolor{red}{递归结构包括两个部分:}
递归结构包括两个部分:
**递归头:**什么时候不调用自身方法。如果没有头,将陷入死循环。
**递归体:**什么时候需要调用自身方法。
5.数组
1.数组概述
数组的定义
- 数组是相同类型数据的有序集合.
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.
2.数组声明创建
- 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar; //首选的方法
或
dataType arrayRefVar[]; //效果相同,但不是首选方法
- Java语言使用new操作符来创建数组,语法如下:
dataType [] arrayRefVar = new dataType [arraySize];
数组的元素是通过素引访问的,数组索引从0开始。
获取数组长度:
arrays.length
public class ArrayDemo01 {
//变量类型 变量的名字 = 变量的值;
//数组类型
public static void main(String[] args) {
int[] nums; //1.(定义首选方法)声明一个数组
nums = new int[10]; //2.创建一个数组
//3.给数组元素赋值
for (int i = 0; i < 10; i++) {
nums[i] = i;
}
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum = sum + nums[i];
}
System.out.println("总和sum为:"+ sum);
}
}
内 存 分 析 : \textcolor{red}{内存分析:} 内存分析:
- 堆:
- 存放new的对象和数组
- 可以被所有的线程共享,不会存放别的对象引用
- 栈:
- 存放基本变量类型(会包含这个基本类型的具体数值)
- 引用对象的变量(会存放这个引用在堆里的具体地址)
- 方法区:
- 可以被所有的线程共享
- 包含了所有的class和static变量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j2FfT6Y5-1647240968145)(1.java%E5%9F%BA%E7%A1%80.assets/image-20220207132848955-16442117342611.png)]
三 种 初 始 化 : \textcolor{red}{三种初始化:} 三种初始化:
- 静态初始化
//静态初始化: 创建 + 赋值
int[] a = {1,2,3,4,5,6,7,8};
- 动态初始化
int[] b = new int[10];
b[0] = 10;
b[1] = 10;
- 默认初始化
数组的四个基本特点:
-
其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
-
其元素必须是相同类型,不允许出现混合类型。
-
数组中的元素可以是任何数据类型,包括基本类型和引用类型。
-
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象, Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,
数 组 对 象 本 身 是 在 堆 中 的 。 \textcolor{red}{数组对象本身是在堆中的。} 数组对象本身是在堆中的。
数组边界
- 数组是相同数据类型的有序集合
- 数组也是对象。数组元素相当于对象的成员变量
- 数组长度是确定的,不可变的.如果越界,则报ArrayIndexOutOfBoundsException
3.数组使用
public class ArraysDemo04 {
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
/*//JDK1.5 没有下标
for (int array : arrays){
System.out.println(array);
}*/
printArray(arrays);
System.out.println();
int[] reverse = reverse(arrays);
printArray(reverse);
}
//打印数组元素
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
//反转数组
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反转操作
for (int i = 0,j=result.length-1; i < arrays.length; i++,j--) {
result[i] = arrays[j];
}
return result ;
}
}
4.多维数组
int[][] array = {{1,2},{2,3},{3,4},{4,5}};
或
int array[][] = {{1,2},{2,3},{3,4},{4,5}};
5.Arrays类
- 数组的工具类java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们便用,从而可以对数据对象进行一些基本的操作
- 查看JDK帮助文档
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用“使用对象来调用(注意:是不用”而不是“不能”)
具有以下常用功能:
-
给数组赋值:通过fill方法。
-
对数组排序:通过sort方法,按升序。
-
比较数组:通过equals方法比较数组中元素值是否相等。
-
查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
import java.util.Arrays; public class ArrayDemo06 { public static void main(String[] args) { int[] a = {1,2,3,4,9090,31231,21,3,23}; System.out.println(a); //[I@14ae5a5 //打印数组元素Arrays.toString System.out.println(Arrays.toString(a)); Arrays.sort(a); //数组进行排序 升序 System.out.println(Arrays.toString(a)); // [1, 2, 3, 3, 4, 21, 23, 9090, 31231] Arrays.fill(a,2,4,0); //[1, 2, 0, 0, 4, 21, 23, 9090, 31231] System.out.println(Arrays.toString(a)); } }
冒 泡 排 序 \textcolor{red}{冒泡排序} 冒泡排序
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a = {1,35,2,6734,34,8,0};
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
//2.每一次比较,都会产生一个最大或者最小的数
//3.下一轮则可以少一次排序
//4.依次循环,直到结束!
public static int[] sort(int[] array){
//临时变量
int temp = 0;
//外层循环,判断我们要走多少次;
for (int i = 0; i < array.length-1; i++) {
//内存循环,判断,交换位置
boolean flag = false; //优化
for (int j = 0; j < array.length-1; j++){
if (array[j+1]<array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if(flag == false){
break;
}
}
return array;
}
}
6.稀疏数组
-
当一个数组中的大部分元素为0.,或者为同一值的数组时,可以使用稀疏数组来保存该数组
-
稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不通知的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
-
如图,左边是原始数组,右边是稀疏数组
public class ArrayDemo08 { public static void main(String[] args) { //1. 创建一个二维数组11*11 0:没有棋子 1:黑棋 2:白棋 int[][] array1 = new int[11][11]; array1[1][2] =1; array1[2][3] =1; //输出原始的数组 System.out.println("输出原始的数组"); for (int [] ints : array1){ for (int anInt : ints){ System.out.print(anInt+"\t"); } System.out.println(); } //转换为稀疏数组保存 //获取有效值个数 int sum = 0; for (int i = 0; i < 11; i++) { for (int j = 0; j < 11; j++) { if (array1[i][j]!=0){ sum++; } } } //2.创建一个稀疏数组的数组 int[][] array2 = new int[sum+1][3]; array2[0][0] = 11; array2[0][1] = 11; array2[0][2] = sum; //遍历二维数组,将非零的值,存放稀疏数组中 int count = 0; for (int i = 0; i < array1.length;i ++) { for (int j = 0; j < array1[i].length; j++) { if (array1[i][j]!=0) { count++; array2[count][0]= i ; array2[count][1]= j ; array2[count][2]= array1[i][j] ; } } } //输出稀疏数组 System.out.println("稀疏数组"); for (int i = 0; i < array2.length; i++) { System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]+"\t"); } System.out.println("================="); System.out.println("还原"); //1.读取稀疏数组 int[][] array3 = new int[array2[0][0]][array2[0][1]]; //2.给其中的元素还原它的值 for (int i = 1; i < array2.length; i++) { array3[array2[i][0]][array2[i][1]] = array2[i][2]; } //3.打印 for (int [] ints : array3){ for (int anInt : ints){ System.out.print(anInt+"\t"); } System.out.println(); } } }
6.面向对象oop
1.初识面向对象
-
面向过程
第一步做什么,第二步做什么
-
面向对象
分类思维模式
面 向 对 象 编 程 的 本 质 : 以 类 的 方 式 组 织 代 码 , 以 对 象 的 方 式 封 装 数 据 \color{red}面向对象编程的本质:以类的方式组织代码,以对象的方式封装数据{} 面向对象编程的本质:以类的方式组织代码,以对象的方式封装数据
-
**三大特性: 封装 继承 多态 **
-
从认识论的角度考虑是先有对象后有类。对象,是具体的事务。类,是抽象的,是对对象的抽象
-
从代码运行角度考虑是先有 类后有对象。类是对象的模板
2.方法回顾和加深
1.方法的定义
1·修饰符
2.返回类型
//Demo01 类
public class Demo01 {
//main方法
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
public String sayHello(){
return "hello,world" ;
}
public int max(int a,int b){
return a>b ? a:b;
}
}
3.break和return的区别
break:跳出switch,结束循环
4.方法名
5.参数列表
6.异常抛出
2.方法的调用
1.静态方法
加了static的方法,static和类一起加载,非静态,类实例化之后才存在
public class Demo02 {
public static void main(String[] args) {
Student.say();
}
}
public class Student {
//非静态方法
public static void say() {
System.out.println("学生说话了");
}
}
2.非静态方法
public class Demo02 {
//实例化这个类 new
//对象类型 对象名=对象值
public static void main(String[] args) {
Student student = new Student();
student.say();
}
}
public class Student {
//非静态方法
public void say() {
System.out.println("学生说话了");
}
}
3.形参和实参
4.值传递和引用传递
//饮用传递
//引用传递
public class Demo04 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); //null
Demo04.change(person);
System.out.println(person.name);
}
public static void change(Person person){
person.name = "董方龙";
}
}
//定义了一个person类,有一个属性:name
class Person{
String name ; //null
}
5.this关键字
3.对象的创建分析
1.类与对象的关系
类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是并不能代表某一个具体的事物
对象是抽象概念的具体实例
2.创建与初始化对象
使用new关键字创建对象:
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下两个特点:
1.必须和类的名字相同
2.必须没有返回类型,也不能写void
//一个项目应该只有一个main方法
public class Application {
public static void main(String[] args) {
//类:抽象的 实例化
//类实例化后会返回一个自己的对象;
//student对象就是一个Student类
Student student = new Student();
Student student1 = new Student();
student.name = "董方龙";
student.age = 22;
System.out.println(student.name);
System.out.println(student.age);
System.out.println(student1.name); //null
student.study();
}
}
//学生类
public class Student {
//属性: 字段
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"学生在学习");
}
}
3.构造器详解
构造器:
- 和类名相同
- 没有返回值
作用:
- new本质在调用构造方法
- 初始化对象的值
注意点:
- 定义有参构造之后,如果使用无参构造,显示的定义一个无参的构造
- Alt+Insert 快捷键
public class Person {
//一个类即使什么都不写,它也会存在一个方法
//显示的定义构造器
String name ;
//实例化初始值
//1.使用new关键字,本质是在调用构造器
//无参构造
public Person(){
this.name = "董方龙";
}
//有参构造:一旦定义了有参构造,无参就必须显示定义
public Person(String name){
this.name = name;
}
}
4.面向对象三大特性
封装 继承 多态
-
封装
高内聚,低耦合。高类聚就是将类的内部数据操作细节自己完成,不允许外部干涉;低耦合,仅暴露少量的方法给外部使用。
数据的隐藏
public class Student {
private String name; //名字
private int id;//学号
private char sex;//性别
//提供一些可以操作这个属性的方法
//提供一些public的get、set方法
//get获得这个数据
public String getName(){
return this.name;
}
//set给这个数据设置值
public void setName(String name){
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
//ALT+SET 自动生成get、set方法
public class Application {
public static void main(String[] args) {
Student s1= new Student();
s1.setName("董方龙");
System.out.println(s1.getName());
}
}
-
继承
通过final修饰的类,不能被继承
继承是类和类之间的一种关系,类和类关系还有:依赖、组合、聚合等
Java类中只有单继承,没有多继承
子类,父类
//在java中,所有的类,都默认直接或间接继承object类
Super详解
注意点:
1.super调用父类的构造方法,必须在构造方法的第一个
2.super必须只能出现在子类的方法的方法或者构造方法中!
3.super和this不能同时调用构造方法。
Vs this:
代表的对象不同:
- this:本身调用者这个对象
- super:代表父类对象的应用
前提:、
- this:没有继承也可以使用
- super:只能在继承条件下才可以使用
构造方法:
- this():本类的构造
- super():父类的构造
方法重写:需要有继承关系,子类重写父类的方法!
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大: public>protected>default>private
- 抛出的异常:范围可以被缩小,但不能扩大: ClassNotFoundException -->Exception
重写,子类的方法和父类的必要一致:方法体不同!
为什么要重写:
- 父类的功能,子类不一定需要,或者不一定满足!
- ALT+Insert @override
- 多态
即同一方法可以根据发送对象的不同而采取不同的行文方式
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
多态存在的条件
有继承关系
子类重写父类方法
父类引用指向子类对象
注意:多态是方法的多态,属性没有多态性
instanceof
- instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
- instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
public class Application {
public static void main(String[] args) {
Object object = new Student();
//Object > String
//Object > Person > Student
//Object > Person > Teacher
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher); //false
System.out.println(object instanceof String); //false
Person person = new Student();
System.out.println(person instanceof Student); //true
System.out.println(person instanceof Person); //true
System.out.println(person instanceof Object); //true
System.out.println(person instanceof Teacher); //false
//System.out.println(person instanceof String); //编译报错!
Student student = new Student();
System.out.println(student instanceof Student); //true
System.out.println(student instanceof Person); //true
System.out.println(student instanceof Object); //true
//System.out.println(student instanceof Teacher); //编译报错!
//System.out.println(student instanceof String); //编译报错!
}
}
5.static关键字详解
package com.dfl.oop.demo07;
//static
public class Student {
private static int age; //静态的变量
private double score; //非静态的变量
public void run(){
System.out.println("run起来了");
}
public static void go(){
System.out.println("go来了");
}
public static void main(String[] args) {
Student student = new Student();
System.out.println(Student.age);
//System.out.println(Student.score); 报错-非静态变量不能通过类名进行访问
System.out.println(student.score);
System.out.println(student.age);
student.run();
go();
//run(); 报错-非静态方法不能直接调用
}
}
package com.dfl.oop.demo07;
public class Person {
//2:赋初值
{
System.out.println("匿名代码块");
}
//1:只执行一次
static {
System.out.println("静态代码块");
}
//3:构造方法
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person = new Person();
System.out.println("========================");
Person person1 = new Person();
}
}
//输出内容:
/*
静态代码块
匿名代码块
构造方法
========================
匿名代码块
构造方法
*/
面向对象:抽象类
概念
-
abstract 修饰符可以用来修饰方法也可以修饰类,
- 如果修饰方法,那么该方法就是抽象方法;
- 如果修饰类,那么该类就是抽象类。
-
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
-
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
-
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
-
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法 ,否则该子类也要声明为抽象类。
面向对象:接口
-
普通类:只有具体实现
-
抽象类:具体实现和规范都有(抽象方法)都有
-
接口:只有规范!
声明类的关键字是class,声明接口的关键字是interface
package com.dfl.oop.demo09; //抽象类: extends~ //类可以实现接口 implements 接口 //实现了接口的类,就需要重写接口中的方法 //多继承~利用接口实现多继承 public class UserServiceImpl implements UserService,TimeService{ @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } @Override public void timer() { } } //========================================================== package com.dfl.oop.demo09; public interface UserService { //接口中的所有定义其实都是抽象的 public abstract void add(String name); void delete(String name); void update(String name); void query(String name); } //============================================================ package com.dfl.oop.demo09; public interface TimeService { void timer(); }
/*作用: 1.约束 2.定义了一些方法,让不同的人实现~ 3,public abstract 4,public static final 5.接口不能被实例化~,接口中没有构造方法~ 6.implements可以实现多个接口 7.必须要重写接口中的方法~ */
6.内部类及OOP实战
内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就是一个内部类,而A类相对于B类来说就是一个外部类。
-
成员内部类
-
静态内部类
- 内部类前面加上static
-
局部内部类
-
匿名内部类
package com.dfl.oop.demo10; public class Test { public static void main(String[] args) { //没有名字初始化类,不用将实例保存到变量中 new Apple().eat(); } } class Apple{ public void eat(){ System.out.println("1"); } }
·
package com.dfl.oop.demo10;
public class Outer {
private int id=10;
public void out(){
System.out.println("这是一个外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性~
public void getID(){
System.out.println(id);
}
}
}
//============================================================
package com.dfl.oop;
import com.dfl.oop.demo10.Outer;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化内部类~
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}
7.异常机制
1.什么是异常
Java 中的异常(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类。
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据。
- 要打开的文件不存在。
- 网络通信时连接中断,或者JVM内存溢出。
这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。
简单分类
- 检查性异常
- 运行时异常
- 错误
2.异常体系机构
-
java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类
-
在java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LLK8S7AV-1647240968146)(1.java%E5%9F%BA%E7%A1%80.assets/12359d729380631b54d307420c3e9bab-16468941445192.png)]
Error
- Error类对象由java虚拟机生成并抛出,大多数错误与代码执行者所执行的操作无关
- java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需要的内存资源时,将出现OutOfMemoryError。这些异常发生时,java虚拟机(JVM)一般会选择线程终止;
- 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为他们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的情况
Exception
- 程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。
3.java异常处理机制
- 抛出异常
- 捕获异常
异常处理五个关键字:
-
try 、catch、finally、throw、throws
package com.dfl.exception; public class Test { public static void main(String[] args) { int a = 1; int b = 0; //假设要捕获多个异常: 从小到大! try { //try监控区域 System.out.println(a / b); } catch (ArithmeticException e) { //catch捕获异常(想要捕获异常的类型) System.out.println("程序出现异常,变量b不能为0"); } catch (Error e){ System.out.println("Error"); } catch (Exception e){ System.out.println("Exception"); } catch (Throwable e){ System.out.println("Throwable"); } finally { //处理善后工作~可以不需要,IO-资源关闭 System.out.println("finally"); } } }
package com.dfl.exception; public class Test2 { public static void main(String[] args) { try { //快捷键 ctrl alt t new Test2().test(1,0); } catch (Exception e) { e.printStackTrace(); } } //假设这方法中,处理不了这个异常。方法上抛出异常 public void test(int a, int b) { if (b == 0) { // 主动地抛出异常 throw throws 一般在方法中使用 throw new ArithmeticException(); } System.out.println(a / b); } }
4.处理异常
5.自定义异常
用户自定义异常类,只需继承Exception类即可。
在程序中自定义异常类,大体可分为以下几个步骤:
创建自定义异常类
在方法中通过throw关键字抛出异常对象。
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步的操作。
在处理异常方法的调用者中捕获并处理异常。
package com.dfl.exception.demo02;
//自定义的异常类
public class MyException extends Exception {
//传递数字>10
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" + detail + '}';
}
}
//====================================================================
package com.dfl.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为:"+a);
if (a > 10){
throw new MyException(a); //抛出
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
e.printStackTrace();
System.out.println("MyException=>"+e);
}
}
}
实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch 处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可以加上 try-catch ,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用 printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源,IO~Scanner
6.总结
e(); } } //假设这方法中,处理不了这个异常。方法上抛出异常
public void test(int a, int b) {
if (b == 0) { // 主动地抛出异常 throw throws 一般在方法中使用
throw new ArithmeticException();
}
System.out.println(a / b);
}
}
## 4.处理异常
## 5.自定义异常
用户自定义异常类,只需继承Exception类即可。
在程序中自定义异常类,大体可分为以下几个步骤:
创建自定义异常类
在方法中通过throw关键字抛出异常对象。
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步的操作。
在处理异常方法的调用者中捕获并处理异常。
```java
package com.dfl.exception.demo02;
//自定义的异常类
public class MyException extends Exception {
//传递数字>10
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" + detail + '}';
}
}
//====================================================================
package com.dfl.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为:"+a);
if (a > 10){
throw new MyException(a); //抛出
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
e.printStackTrace();
System.out.println("MyException=>"+e);
}
}
}
实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch 处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可以加上 try-catch ,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用 printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源,IO~Scanner