Java基础知识
1、冯诺依曼体系结构
2、电脑常用的快捷键
Ctrl+C:复制
Ctrl+V:粘贴
Ctrl+A:全选
Ctrl+X:剪切
Ctrl+Z:撤销
Ctrl+S:保存
Alt+F4:关闭窗口
Shift+Del:永久删除
win+R:运行
win+E:打开我的电脑
Ctrl+Shift+Esc:打开任务管理器
win+Tab:切换应用程序
win+D:返回电脑桌面
3、Dos命令
#盘符切换 D:
#查看当前目录下的文件 dir
#切换目录 cd change directory
cd ..
#清理屏幕 cls (clear screen)
#退出终端 exit
#查看电脑的ip ipconfig
#打开应用
calc(计算器)
mspaint(画图软件)
notepad(记事本)
# ping命令
ping www.baidu.com
#文件操作
md 目录名(创建目录)
rd 目录名(删除目录)
cd> 文件名(创建文件,包含后缀)
del 文件名(删除文件)
4、JDK
1、卸载JDK
- 删除Java的安装目录
- 删除JAVA_HOME
- 删除path下关于Java的目录
- 用java -version检查java是否还存在
2、安装JDK
- 百度搜索JDK8,找到下载地址,oracle官网中
- 同意协议
- 下载电脑操作系统对应的多少位的版本
- 双击安装JDK
- 记住安装的路径
- 配置环境变量
- 我的电脑–>右键–>属性
- 环境变量–>JAVA_HOME
- 配置path变量
- 测试JDK是否安装成功
- 打开cmd
- 输入java -version
IDEA官网:https://www.jetbrains.com/
5、Java基础语法
1、注释
- 单行注释
//System.out.println();
- 多行注释
/*
注释内容
*/
- 文档注释
/**
*
*/
2、标识符
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
关键字:
标识符注意点:
- 所有的标识符都应该以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始;
- 首字符之后可以是字母(A-Z或者a-z),美元符($)、或者下划线(_)或者数字的任何字符组合;
- 不能使用关键字作为变量名或方法名;
- 标识符是大小写敏感的;
- 合法标识符举例:age、$salary、_value、_1_value;
- 非法标识符举例:123abc、-salary、#abc;
- 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音,很Low;
3、变量
什么是变量:就是可以变化的量;
Java是一种强类型语言,每个变量都必须声明其类型;
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域;
//数据类型 变量名 = 值; 可以使用逗号隔开来声明多个同类型变量。
变量的命名规范
- 所有变量、方法、类名:见名知意;
- 类成员变量:首字母小写和驼峰原则(小驼峰命名法);
- 局部变量:首字母小写和驼峰原则(小驼峰命名法);
- 常量:大写字母和下划线;
- 类名:首字母大写和驼峰原则(大驼峰命名法);
- 方法名:首字母小写和驼峰原则(小驼峰命名法);
注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是一弄类型;
- 变量名必须是合法的标识符;
- 变量声明是一条完整的语句,因此每个声明都必须以分好结束;
变量有三种类型:
类变量(从属于类);
实例变量(从属于对象);
局部变量(在某个作用域内有效);
4、常量
常量:初始化后不能再改变值,不会变动的值;
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变;
final double PI = 3.14;
常量名一般使用大写字符;
5、运算符
- Java语言支持如下运算符:
- 算术运算符:+,-,*,/,%,++,–(int类型以上的运算,以其为标准;以下如:short+byte,统统改为int再进行运算,结果为int)
- 赋值运算符:=
- 关系运算符:>, <, >=, <=, ==, !=, instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,……,~,>>,<<,>>>
- 条件运算符:? :
- 扩展赋值运算符:+=,-=,*=,/=
指针最优,单目运算优于双目运算。如正负号。先乘除,后加减。先算术运算,后移位运算,最后位运算。逻辑运算最后计算
单目算术位关系,逻辑三目后赋值。
6、包机制
- 为了更好地组织类,Java提供了 包机制,用于区别类名的命名空间;
- 包语句的语法格式为:
package com....
- 一般利用公司域名倒置作为包名:
- 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包,使用import语句可完成此功能;
import com...
7、Java Doc
- javaodc命令是用来生成个自己API文档的
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
使用命令行生成doc文档:
javadoc -encoding UTF-8 -charset UTF-8 Test.java
8、switch多选择结构
Java三种结构:顺序结构、选择结构和循环结构;
- 多选择结构还有一个实现方式就是switch case语句;
- switch case语句判断一个变量与一系列值中某个值是否相等,每个值成为一个分支。
- switch语句汇中的变量类型可以是:
- byte、short、int或者char
- 从Java SE 7 开始,switch支持字符串String类型了
- 同时case标签必须为字符串常量或字面量
- JDK1.5起switch语句支持Enum枚举值
9、方法
1、方法定义
-
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含一下语法:
-
方法包含一个方法头和一个方法题,下面是一个方法的所有部分:
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型。
-
返回值类型:方法可能会返回值,returnValueType是方法返回值的数据类型,有些方法执行所需的操作,但没有返回值,在这种情况下,returnValueType是关键字void。
-
方法名:是方法的实际名称,方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符,当方法被调用时,传递值给参数,这个值,被称为实参变量,参数列表是指方法的参数类型、顺序和参数的个数,参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用是用于接受外界输入的数据。
- 实参:调用方法时实际传递给方法的数据。
方法体:方法体包含具体的语句,定义该方法的功能。
-
2、方法调用
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值来选择。
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30, 40);
如果方法返回值是void,方法调用一定是一条语句。
System.out.println("Hello,kuangshen!");
可变参数
- JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。
10、递归
- A方法调用B方法,我们很容易理解!
- 递归就是:A方法调用A方法!就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么是否需要调用自身方法。
11、数组
1、数组声明创建
- 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar; //首选的方法
或
dataType arrayRefVar[]; //效果相同,但不是首选方法
- Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
- 数组的元素是通过索引访问的,数组索引从0开始。
- 获取数组长度:arrays.length
2、三种初始化
- 静态初始化
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;
- 数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
3、数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量,数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他独享类型,数组对象本身是在堆中的。
4、数组边界
- 下标的合法区间:[0,length-1],如果越界就会报错;
- ArrayIndexOutOfBoundsException:数组下标越界异常!
- 小结:
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合。
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度确定的,不可变的。如果越界,则报:ArrayIndexOUtBounds。
5、多维数组
- 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
- 二维数组
int a[][] = new int[2][5];
- 解析:以上二维数组a可以看成一个两行五列的数组。
6、Arrays类
- 数组的工具类java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
- 查看JDK帮助文档
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
- 具有以下常用功能:
- 给数组赋值:通过fill方法。
- 对数组排序:通过sort方法,按升序。
- 比较数组:通过equals方法比较数组中元素值是否相等。
- 查找数组元素:通过binarySearch方法能耐对排序号的数组进行二分查找法操作。
7、稀疏数组介绍
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值。
- 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
- 如下图:左边是原始数组,右边是稀疏数组:
举个例子:
package com.lq.learn.base.arr;
import sun.security.util.Length;
import java.util.Arrays;
/**
* @author Hasee
*/
public class SparseArray {
public static void main(String[] args) {
int[][] a = new int[10][10];
a[1][2] = 6;
a[3][4] = 8;
show(a);
int sum=0 ;
//计算有效值
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if(a[i][j]!=0){
sum++;
}
}
}
//稀疏数组
int[][] ints = new int[sum + 1][3];
ints[0][0] = a.length;
ints[0][1] = a[0].length;
ints[0][2] = sum;
int count = 1;
System.out.println("======================================");
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if(a[i][j]!=0){
ints[count][0] = i;
ints[count][1] = j;
ints[count][2] = a[i][j];
count++;
}
}
}
show(ints);
System.out.println("=========================");
//稀疏数组还原
int[][] old = new int[ints[0][0]][ints[0][1]];
for (int i=1 ;i<=ints[0][2];i++){
old[ints[i][0]][ints[i][1]]=ints[i][2];
}
show(old);
}
public static void show(int[][] a) {
if (a != null && a.length > 0) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j]+"\t");
}
System.out.println();
}
}
}
}
12、面向对象
#####1、面向过程&面向对象
面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面像过程适合处理一些较为简单的问题
面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的死锁。
- 面向对象适合处理复杂的问题,适合处理需要多人写作的问题!
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是具体到微观操作,仍然需要面向剁成的思路去处理。
2、什么是面向对象
面向对象编程(OOP)的本质就是:以类的方式组织代码,以对象组织(封装)数据。
抽象
三大特性:
- 封装
- 继承
- 多态
从认识论角度考虑是先有对象后有类。对象,是具体的事务。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后又对象,类是对象的模板。
13、封装
- 该露的露,该藏的藏
- 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
- 分装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 记住这句话就够了:属性私有,get/set。
14、继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
-
extends的意思是“扩展”,子类是父类的扩展。
-
Java中类只有单继承,没有多继承!
-
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合等。
-
继承关系的两个类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键字extends来表示。
-
子类和父类之间,从意义上讲应该具有“is a"的关系。
Object类:万类之祖
super - this(子类的无参构造方法会隐式的调用父类的无参构造方法,子类有的有参构造方法的第一行一定是super(…))=
super注意点:
1、super调用父类的构造方法,必须在构造方法的第一个;
2、super必须只能出现在子类的方法或者构造方法中!
3、super和this不恩能同时调用构造方法!
Vs this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的引用
前提:
this:没有继承也可以使用
super:是能在继承条件下可以使用
构造方法
this():本类的构造
super():父类的构造
方法重写(前提非静态的方法):
- 静态的方法和非静态的方法区别很大!
- 静态的方法:方法的调用之和左边定义的数据类型有关;
- 非静态的方法:方法的调用与右边new的对象有关;
重写:需要有继承关系,子类重写父类的方法!
1、方法名必须相同
2、参数列表必须相同
3、修饰符:范围可以扩大但不能缩小(子类不能比父类更自私):public>protected>default>private
4、抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException --> Exception
重写,子类的方法和父类必须一致;方法提不同!
为什么需要重写:
1、父类的功能,子类不一定需要,或者不一定满足;
父类的引用可以指向子类对象;
15、多态
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
-
多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
-
主义:多态是方法的多态,属性没有多态性。
Person s1 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边的关系不大!
//子类重写了父类的方法,真正执行子类的方法
16、抽象类
-
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
-
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
-
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
-
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
-
子类继承抽象类,那么就必须要实现抽象类;没有实现抽象方法,那么该子类也要声明为抽象类。
17、接口
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有
-
接口:只有规范!自己无法写方法。专业的约束! 约束和实现分离:面向接口编程
-
接口就是规范,定义的是一组规则。
-
接口的本质是契约,就像我们人的法律一样,制定好后大家都遵守;
接口的作用:
- 约束
- 定义一些方法,让不同的人实现不同的功能
- 默认方法修饰符:public abstract
- 默认属性修饰符:public static final
- 接口不能被实例化,接口中没有构造方法
- implements可以实现多个接口
- 必须要重写接口中的方法
18、异常
简单分类
- 要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在的文件时,一个异常就发生了,这些异常在编译时不能被简单的忽略。
- 运行时异常:运行时异常时可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误:错误不是异常,而是脱离程序员控制的问题,错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时也检查不到的。
异常体系结构
-
Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类;
-
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
Error
- Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关;
- Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
- 还有发生在虚拟机视图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数程序运行时不允许出现的状况。
Exception
- 在Exception分支中有一个重要的子类RuntimeException(运行时异常)
- ArrayIndexOutOfBoundsException(数组下标越界)
- NullPointerException(空指针异常)
- ArithmeticException(算术异常)
- MissingResourceException(丢失资源)
- ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
- 这些异常一般都是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
- Error和Exception的区别:Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
自定义异常
-
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
-
在程序中使用自定义异常类,大体可分为以下几个步骤:
- 创建自定义异常类;
- 在方法中通过throw关键字抛出异常对象;
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法声明处通过throws关键字致命要抛出给方法调用者的异常,继续进行下一步操作;
- 在出现异常方法的调用者中捕获并处理异常;
6、补充知识
1、值传递和引用传递:
Java 中数据类型分为两大类,基本类型和引用类型。相应的,变量也有两种类型:基本类型和引用类型。
1️⃣基本类型的变量保存原始值,即它代表的值就是数值本身。包含:
整型:byte,short,int,long
浮点型:float,double
字符型:char
布尔型:boolean
2️⃣引用类型的变量保存引用值,“引用值”指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。包含:
数组
类
接口
变量的基本类型和引用类型的区别:
-
基本数据类型在声明时系统就给它分配空间:
-
引用则不同,它声明时只给变量分配了引用空间,而不分配数据空间(在new的时候才会在内存中开辟一块空间):
值传递
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。
官方解释:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址。在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。
官方解释:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
java中都是值传递
java在方法传递参数时,是将变量复制一份,然后传入方法体去执行。
可参考博客:https://blog.csdn.net/qq_39552268/article/details/111415291
2、高内聚、低耦合
高内聚:尽可能类的每个成员方法只完成一件事;
低耦合:减少类内部,一个成员方法调用另一个成员方法;
核心思想,尽可能减少代码耦合,如果发现代码耦合,就要采取解耦技术。让数据模型,业务逻辑和视图显示三层之间彼此降低耦合,把关联依赖降到最低,而不至于 “牵一发而动全身”。