一、字节(计算机中最小的存储单元)
--右键点击文件属性,可查看文件的字节大小
8个bit(二进制位) 0000-0000表示为1个字节,写做1byte或者1B
*8bit=1Byte
*1024B=1KB
*1024KB=1MB
*1024MB=1GB
*1024GB=1TB
*1024TB=1PB
*1024PB=1EB
*1024EB=1ZB
二、命令提示符(command)-【cmd】
MS-DOS(Microsoft Disk Operating System)
启动: win+R,输入cmd回车
切换盘符: 盘符名称:
进入文件夹 cd 文件夹名称
进入多级文件夹 cd 文件夹1\文件夹2\文件夹3
返回上一级 cd …
直接返回根路径 cd
查看当前内容 dir
清屏 cls
退出 exit
三、JVM(Java Virtual Machine)–java虚拟机–【是运行所有java程序的假想计算机,是java程序的运行环境】
【java语言的跨平台性】:我们用java编写的软件可以在任何的操作系统上运行
注意:java的虚拟机本身不具备跨平台功能的,每个操作系统下都有不同版本的虚拟机(JVM运行在操作系统上)
JRE(Java Runtime Environment)-【是java程序的运行时环境,包含JVM和运行时所需要的核心类库】
JDK(Java Development Kit)-【是java程序开发工具包,包含JRE和恶开发人员使用的工具】
包含关系:
JDK {编译器等开发工具+JRE}
JRE {运行类库+JVM}
四、程序开发步骤
1、编写源程序(.java)
2、编译源程序(编译器-javac.exe)-java字节码文件(解释器-java.exe)
3、运行(JVM运行)
五、数据类型分类
1、基本数据类型
整数型 byte short int long
浮点型 float double
字符型char
布尔型 boolean
2、引用数据类型
字符串、数组、类、接口、 Lambda
3、注意事项:
1、字符串不是基本类型,而是引用类型
2、浮点型可能只是一个近似值,并非精确的值
3、数据范围与字节数不一定相关,例如float数据范围比long更加广泛, float但是是4字节,1ong是8字节
4、浮点数当中默认类型是 Ldouble.如果一定要使用 float类型,需要加上一个后缀F
5、如果是整数,默认为int类型如果一定要使用ong类型,需要加上一个后L推荐使用大写字母后缀
6、jdk1.5以后,字符可以和整数进行转化 eg:char i=45;
public class Demo02Variable{
public static void main(String[] args){
//创建一个变量
//格式:数据类型变量名称;
int numl;
//向变量当中存入一个数据
//格式:变量名称=数据值;
num1 =10;
//当打印输出变量名称的时候,显示出来的是变量的内容
System.out. printIn(num1); //10
//改变变量当中本来的数字,变成新的数字
num1=20;
System.out. printIn(num1); //20
//使用一步到位的格式来定义变量
//格式:数据类型变量名称=数据值;
int num2 =253
System. out. printIn(num2); //25
num2 =35;
System.out. printIn(num2); //35
System.out. printIn("====");
byte num3=30;//注意:右侧数值的范围不能超过左侧数据类型的取值范围
System.out. printIn(num3);//30
byte num44=400;//右侧超出了byte数据范围,错误!
short num5 =50;
System. out. printIn(num5); //150
long num6 3000000000L;
System.out. println(num6); //3000000000
float num7 =2.5F;
System. out. printIn(num7); //2.5
double num8=1.2;
System. out.printIn(num8); //1.2
char ziful ='A';
System. out. println(zifu1);/ / A
zifu1=‘中’
System.out. println(zifu1);//中
boolean varl true;
System.out. printIn(var1); //true
var1=false;
System.out. println(var1); // false
//将一个变量的数据内容,赋值交给另一个变量
//右侧的变量名称var1已经存在,里面装的是 false布尔值
//将右侧变量里面的 false值,向左交给var2变量进行存储
boolean var2=varl;
System.out. println(var2); // false
}
}
六、【方法】
1、“ 方法 ” 好比是 个工厂。
蒙牛工厂 原料: 招牛、饲料、水
产出物 奶制品
钢铁工厂 原料、铁矿石、煤炭
产出物 钢锈建村
参数(原料): 就是进入方法的数据。
返回值(产出物): 就是从方法中出来的数据。
2、定义方法的完整格式:
修饰符 返回值类型 方法名称(参数类型 参数名称,…){
方法体
return 返回值;
}
3、解析
修饰符:(现阶段的固定写法)public static
逗回值类型: 也就是方法最终产生的数据结果是什么类型
方法名称: 方法的名字,现则和变量一样,小驼峰
参数类型:进入方法的数据是什么类型
参数名称: 进入方法的数据对应的变量名称
PS: 参数如果有多个,使用逗号进行分隔
”return“两个作用:第一是停止当前方法,第二是将后面的返回值还给调用处
返回值: 也就是方法只执行后最终产生的数据结果
注意:
retunn后面的“近回值”,必须和方法名称前面的“近回值类型”,保持对应。
4、明确方法三要素:
1、返回值类型
2、方法名称(小驼峰)
3、参数列表
5、三种调用“方法”的格式:
1、单独调用【直接写:方法名称(参数);】
2、打印调用【利用返回值:System.out.println(方法名称(参数));】
3、赋值调用【利用返回值:数据类型 变量名称=方法名称(参数);】
6、方法调用的流程:
1、找到方法(编写方法)
2、传递参数
3、执行方法体
4、带着返回值回到方法调用处
7、对比方法有参数和无参数:
有参数:小括号内有内容,一个方法需要一定数据条件,才能完成任务;
eg:两个数字相乘,必须知道这两个数字各是多少,才能相加。
无参数:小括号内留空,一个方法不需要任何数据条件,自己就能独立完成任务;
eg:定义一个方法,打印固定10次”Helloworld“。
8、对比方法有返回值和无返回值:
注意:
对于有返回值的方法,可以使用单独调用、打印调用或者赋值调用;
对于无返回值的方法,只能使用单独调用,不能使用打印调用或者赋值调用;
9、方法习题:判断两个数字是否相同
public static boolean isSame(int a,int b){
/*boolean same;
if(a==b){
same=ture;
}else{
same=false;
}
return same;*/ 【1】
/*boolean same=a==b?ture:false;
return same;*/【2】
/*boolean same=a==b;
return same;*/【3】
/*boolean same;
return a==b;(确定返回值是布尔类型即可;)*/【4】
//boolean same;
if(a==b){
return ture;}
else{
return flase;} 【5】
}
10、使用方法时的注意事项:
1、方法应该定义在类当中,但是不能在方法当中再定义方法。不能嵌套。
2、方法定义的前后顺序无所谓。
3、方法定义之后不会执行,如果希望执行,一定要调用:单独调用、打印调用、赋值调用。
4、如果方法有返回值,那么必须写上“return 返回值;”,不能没有。
5、 return后面的返回值数据,必须和方法的返回值类型,对应起来。
6、对于一个void没有返回值的方法,不能写return后面的返回值,可以写return自己。(即没有返回值,只是结束方法的执行而已)
7、对于void方法当中最后一行的return可以省略不写。
8、一个方法当中可以有多个return语句,但是必须保证同时只有一个会被执行到,两个return不能连写。
*11、【方法的重载(overload)】:*多个方法的名称一样,但是参数列表不一样。
好处:只需要记住唯一的一个方法名称,就可以实现类似的多个功能。
【注意事项】:
方法重载与下列因素相关:
1、参数个数不同
2、参数类型不同
3、参数的多类型顺序不同
方法重载与下列因素无关:
1、与参数的名称无关
2、与参数的返回值无关
12、方法重载的习题:
1、比较两个数据是否相等。
(参数类型分别为两个byte类型,两个short类型,两个int类型,两个long类型)
2、判断方法的正确重载
3、实现重载的println方法
(在调用输出语句的时候,println方法其实就是进行了多种数据类型的重载形式。)
七、Java的内存需要划分成为5个部分:
1、栈(Stack): 存放的都是方法中的局部变量。
方法的运行一定要在栈当中运行。
局部变量: 方法的参数,或者是方法 (内部的变量作用域:一旦超出作用域,立刻从栈内存当中消失。)
2、堆(Heap): 凡是new出来的东西,都在堆当中。
堆内存里面的东西都有一个地址值: 【16进制堆内存里面的数据,都有默认值。】规则:
如果是整数 默认为0
如果是浮点数 默认为0.0
如果是字符 默认为"\u0000
如果是布尔 默认为false
如果是引用类型 默认为null
3、方法区(MethodArea): 存储 .class 相关信息,包含方法的信息。
4、本地方法栈(Native Method Stack): 与操作系统相关
5、寄存器(pc Register):与CPU相关。
八、数组
1、数组的概念: 是一个容器,可以同时存放多个数据值。
2、数组的特点:
1、数组是一种引用数据类型
2、数组当中的多个数据,类型必须统一
3、数组的长度在程序运行期间不可改变
3、数组的初始化:
在内存当中创建一个数组,并且向其中赋予一些默认值。
4、两种常见的初始化方式:
1、动态初始化【指定长度】
2、静态初始化【指定内容】
动态初始化 (指定长度) : 在创建数组的时候,直接指定数组当中的数据元素个数。
静态初始化 (指定内容) : 在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。
5、动态初始化数组的格式:
数据类型 [ ] 数组名称 = new 数据类型 [ 数组长度 ] ;
解析含义:
左侧数据类型: 也就是数组当中保存的数据,全都是统一的什么类型
左侧的中括号: 代表我是一个数组
左侧数组名称: 给数组取一个名字右侧的new:代表创建数组的动作
右侧数据类型: 必须和左边的数据类型保持一致
右侧中括号的长度: 也就是数组当中,到底可以保存多少个数据,是一个int数字
public class Demo01Array {
public static void main(String[] args){
//创建一个数组,里面可以存放300个int数据
//格式:数据类型数组名称new数据类型[数组长度];
int[] arrayA = new int[300];
//创建一个数组,能存放10个double类型的数据
double[] arrayB = new double[10];
// 创建一个数组,能存放5个字符串
String [ ] arrayC = new String [5];
}
}
6、静态初始化基本格式:
数据类型 [ ] 数组名称 = new 数据类型 [ ] { 元素1,元素2,…};
注意事项:
虽然静态初始化没有直接告诉长度,但是根据大括号里面的元素具体内容,也可以自动推算出来长度。
public class Demo02Array {
public static void main(String[] args){
//直接创建一个数组,里面装的全都是int数字,具体为:5、15、25
int [ ] arrayA = new int[ ]{ 5, 15, 25, 40 };
//创建一个数组,用来装字符串:"Hello"、"World"、"Java”
String [ ] arrayB = new String [ ] {"Hello","World","Java");
}
}
(使用 静态初始化数组 的时候,格式还可以省略一下)
标准格式:
数据类型 [ ] 数组名称 = new 数据类型 [ ] { 元素1,元素2,… };
省略格式:
数据类型 [ ] 数组名称 = { 元素1,元素2,…}
7、注意事项:
1、静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
2、静态初始化标准格式可以拆分成为两个步骤,但静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。
3、动态初始化也可以拆分成为两个步骤。
public class Demo03Array {
public static void main(String[] args){
//省略格式的静态初始化
int [ ] arrayA ={ 10,20,30 };
//静态初始化的标准格式,可以拆分成为两个步骤
int [ ] arrayB;
arrayB = new int [ ] { 11, 21,31 };
//动态初始化也可以拆分成为两个步骤
int [ ] arrayC;
arrayC = new int [5];
//静态初始化的省略格式,不能拆分成两个步骤。
int [ ] arrayD;
arrayD = {10, 20, 30};
}
}
8、数组访问
1、直接打印数组名称,得到的是数组对应的: 内存地址哈希值。
(二进制:01
十进制: 0123456789
16进制: 0123456789abcdef)
2、访问数组元素的格式: 数组名称 [索引值]
【索引值】: 就是一个int数字,代表数组当中元素的编号。
【注意】索引值从0开始,一直到“数组的长度-1”为止。
public class Demo04ArrayUse {
public static void main(String[] args){
//静态初始化的省略格式
int [ ] array ={ 10,20,30};
System.out.println(array); // [I@75412c2f (数组+int型+@+十六进制)
//直接打印数组当中的元素
System.out.println(array[0]); // 10
System.out.println(array[1]); //20
System.out.println(array[2]);//30
//也可以将数组当中的某一个单个元素,赋给变量
int num =array[1];
System.out.println(num);//20
}
}
3、(使用 动态初始化数组 的时候,其中的元素将会自动拥有一个默认值。)
规则如下:
如果是整数类型 默认为0;
如果是浮点类型 默认为0.0;
如果是字符类型 默认为‘\u0000’;
如果是布尔类型 默认为false;
如果是引用类型 默认为null;
public class Demo05ArrayUse {
public static void main(String[] args){
//动态初始化一个数组
int[] array = new int[3];
System.out.println(array);// 内存地址值
System.out.println(array[0]); //0
System.out.println(array[1]);//0
System.out.println(array[2]);//0
}
}
9、数组反转
【int[] arr =new int [] {4,2,7,1,3,5};
//考虑声明一个数组temp,数组temp的长度和arr数组长度一致,我们倒着循环arr数组,但是正着给temp数组元素赋值。
//temp就是arr的倒序数组,然后再把temp赋值给arr(arr=temp)
//一个数组的最后一个元素,它的下标等于数组的长度-1,因为元素的下标是从0开始。
int[] temp =new int[arr.length];
int k=0;//这是temp数组中元素的下标。
for(int i=arr.length-1;i>=0;i--)
{
System.out.println(arr[i]);
temp[k]=arr[i];//第一次循环,k=0,i=5相当于temp[0]=arr[5];
k++;
}
arr=temp;
for(int i=0;i<aarr.length;i++)
{
System.out.println(arr[i]);
}
10、数组赋值 != 复制
【注意:复制不等于赋值】
int[] a=arr;//赋值
int[] copy=new int[arr.length];//声明一个与arr数组长度一致的数组
for(int i=0;i<arr.length;i++)//复制
{
copy[i]=arr[i];//遍历arr数组,把arr数组中的每一个元素安装顺序拿出来,并给copy数组的每一个元素赋值,在这里的i就是copy和arr数组中元素的下标
}
11、数组排序
九、Private关键字的作用和使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9tgkMXgt-1628557971535)(C:\Users\25510\AppData\Roaming\Typora\typora-user-images\image-20210207223053865.png)]
间接访问:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-noSAj1MX-1628557971537)(C:\Users\25510\AppData\Roaming\Typora\typora-user-images\image-20210207223233095.png)]
注意:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ASUhPKtD-1628557971539)(C:\Users\25510\AppData\Roaming\Typora\typora-user-images\image-20210207223639177.png)]
十、final关键字
定义常量:
final + 常量数据类型 + 常量名称(纯大写)+(常量值);
【只能定义一次】
十一、Scanner类注意事项
1、nextLine()方法会吃回车符
2、如果要输入带空格的字符串的话,可以添加in.nextLine();语句吃掉回车符
3、最后补充一下nextLine()和next()的区别:
nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。
next()会自动消去有效字符前的空格,只返回输入的字符,不能得到带空格的字符串。
十二、模式
单例模式
单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在。
饿汉式单例模式
GiantDragon 应该只有一只,通过私有化其构造方法,使得外部无法通过new 得到新的实例。
GiantDragon 提供了一个public static的getInstance方法,外部调用者通过该方法获取12行定义的对象,而且每一次都是获取同一个对象。 从而达到单例的目的。
这种单例模式又叫做饿汉式单例模式,无论如何都会创建一个实例
package charactor;
public class GiantDragon {
//私有化构造方法使得该类无法在外部通过new 进行实例化
private GiantDragon(){
}
//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
private static GiantDragon instance = new GiantDragon();
//public static 方法,提供给调用者获取12行定义的对象
public static GiantDragon getInstance(){
return instance;
}
}
package charactor;
public class TestGiantDragon {
public static void main(String[] args) {
//通过new实例化会报错
// GiantDragon g = new GiantDragon();
//只能通过getInstance得到对象
GiantDragon g1 = GiantDragon.getInstance();
GiantDragon g2 = GiantDragon.getInstance();
GiantDragon g3 = GiantDragon.getInstance();
//都是同一个对象
System.out.println(g1==g2);
System.out.println(g1==g3);
}
}
懒汉式单例模式
懒汉式单例模式与饿汉式单例模式不同,只有在调用getInstance的时候,才会创建实例
-
package charactor;
public class GiantDragon {
//私有化构造方法使得该类无法在外部通过new 进行实例化 private GiantDragon(){ } //准备一个类属性,用于指向一个实例化对象,但是暂时指向null private static GiantDragon instance; //public static 方法,返回实例对象 public static GiantDragon getInstance(){ //第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象 if(null==instance){ instance = new GiantDragon(); } //返回 instance指向的对象 return instance; }
}
package charactor;
public class TestGiantDragon {
public static void main(String[] args) {
//通过new实例化会报错
// GiantDragon g = new GiantDragon();
//只能通过getInstance得到对象
GiantDragon g1 = GiantDragon.getInstance();
GiantDragon g2 = GiantDragon.getInstance();
GiantDragon g3 = GiantDragon.getInstance();
//都是同一个对象
System.out.println(g1==g2);
System.out.println(g1==g3);
}
}
什么时候使用饿汉式,什么时候使用懒汉式
饿汉式,是立即加载的方式,无论是否会用到这个对象,都会加载。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。
懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量(鉴于同学们学习的进度,暂时不对线程的章节做展开)。
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。
看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式
单例模式三元素
这个是面试的时候经常会考的点,面试题通常的问法是:
什么是单例模式?
回答的时候,要答到三元素
\1. 构造方法私有化
\2. 静态属性指向实例
\3. public static的 getInstance方法,返回第二步的静态属性
十三、集合
<1>集合与数组的区别
(1)长度区别:集合长度可变,数组长度不可变
(2)内容区别:集合可存储不同类型元素,数组存储只可单一类型元素
(3)元素区别:集合只能存储引用类型元素,数组可存储引用类型,也可存储基本类型
<2>集合框架
1、List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
2、Set被HashSet类实现,被LinkedHashSet继承。同时TreeSet类实现SortedSet接口、LinkedHashSet 类继承HashSet类。
3、List下有ArrayList,Vector,LinkedList三个实现类
4、Map下有Hashtable,HashMap两个实现类,被SortedMap接口继承,同时TreeMap类实现SortedMap接口,Propertise类继承HashTable类
5、Collection接口下还有个Queue接口,有PriorityQueue类
【Collection接口是单列集合的最顶层接口,定义了一些通用的方法。
add(E e)添加元素; clear()清空元素; remove(E e)移除元素; szie()元素数量;
toArray()集合转数组; contains(E e)判断元素是否存在; isEmpty()判断集合是否为空;
原文链接:https://blog.csdn.net/weixin_42559574/article/details/108203595】
Connection接口:
— List 有序,可重复
1、ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
2、Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
3、LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高
—Set 无序,唯一
一、HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()
二、LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一
三、TreeSet
底层数据结构是红黑树。(唯一,有序)
- 如何保证元素排序的呢?
自然排序
比较器排序 - 如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
{
针对Collection集合我们到底使用谁呢?(掌握)
唯一吗?
是:Set
排序吗?
是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。
否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。
如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
如果你知道用集合,就用ArrayList。
}
【原文链接:https://blog.csdn.net/zhangqunshuai/article/details/80660974】
Map接口(双列集合)
特点:元素包含两个值(key,value)即键值对, key不允许重复,value可以重复, key与value是一一对应的。元素无序;
Map接口是双列集合的最顶层接口,定义了一些通用的方法。
put(key , value) 添加元素; remove(key) 删除key对应元素;
containsKey(key) 判断是否存在key对应元素;get(key) 获取key对应元素;
KeySet() 获取所有的key,存到Set集合中;entrySet() 获取所有的元素,存到Set集合中;
ps:Map集合必须保证保证key唯一,作为key,必须重写hashCode方法和equals方法,以保证key唯一。
【原文链接:https://blog.csdn.net/weixin_42559574/article/details/108203595】
一、HashMap实现类
数据结构:JDK1.8之前:哈希表(数组+单向链表);JDK1.8之后:哈希表(数组+单向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。
特点:查询快,元素无序,key不允许重复但可以为null,value可以重复。
底层分析:和HashSet底层相类似,不赘述。
二、LinkedHashMap实现类
数据结构:JDK1.8之前:哈希表(数组+双向链表);JDK1.8之后:哈希表(数组+双向链表+红黑树),当链表长度超过阈值(8)时,链表将转换为红黑树。
特点:查询快,元素有序,key不允许重复但可以为null,value可以重复。
底层分析:和LinkedHashSet底层相类似,不赘述。
三、HashTable实现类(基本不用)
数据结构:哈希表
特点:查询快,元素无序,key不允许重复并且不可以为null,value可以重复。
底层分析:HashTable和Vector一样是古老的集合,有遗留缺陷,在JDK1.2之后 被更先进的集合取代了;HashTable是线程安全的,速度慢,HashMap是线程不安全的,速度快;
ps:Hashtable的子类Properties现在依然活跃,Properties集合是一个唯一和IO流结合的集合。
四、treeMap实现类
数据结构:红黑树
特点:查询快,元素有序,key不允许重复并且不可以为null,value可以重复。
底层分析:和TreeSet底层相类似,不赘述。
十四、面向对象
面向对象包括三大特征:
——封装
——继承
——多态
1>、当前主要讲解的是封装机制。为什么要封装?封装有什么好处?
封装的好处:
1、封装之后,对于那个事物来说,看不到这个事物比较复杂的那一面,只能看到该事物简单的那一面。复杂性封装,对外提供简单的操作入口。
{ 照相机就是一个很好的封装的案例,照相机的实现原理非常复杂但是对于使用照相机的人来说,操作起来是非常方便的是非常便捷的。还有像电视机也是封装的,电视机内存实现非常复杂,但是对于使用者来说不需要关心内部的实现原理,只需要会操作遥控器就行。}
2、封装之后才会形成真正的”对象”,真正的”独立体”
3、封装就意味着以后的程序可以重复使用。并且这个事物应该适应性比较强,在任何场合都可以使用。
4、封装之后,对于事物本身,提高了安全性。【安全级别高】
2>、自定义类的对象
1、当一个对象作为参数,传递到方法当中时,实际上传递进去的是对象的地址值。
2、当使用对象类型作为方法的返回值,返回值其实是对象的地址值。
3>、多态性【一个对象拥有多个形态:对象的多态性】
1、extends继承或者implements实现,是多态性的前提。
2、代码当中体现多态性【Polymorphism】:父类引用指向子类对象【左父右子】
格式:
父类名称 对象名 =new 子类名称();
eg:Fu obj =new Zi () ;//左侧父类的引用,指向右侧子类的对象
或者:
接口名称 对象名 =new 实现类名称();
十五、异常(程序在执行过程中出现的非正常的情况,最终会导致VM的 非正常 停止)
在ava等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
异常不是语法错误。
(语法错了,编译不通过,不会产生字节码文件,根本不能运行)
异常体系
帮助我们找到程序中的问题,异常的根类是java.langThrowable【所有异常和错误的父类(超类),其下有两个子类: java.lang.Error【无法处理,只能尽量避免】与java.lang.Exception【由于使用不当导致即“编译期异常,可以避免】、(平常所说的异常指java.lang.Exception.——特殊:RuntimeException【运行期异常】)
十六、API文档【jdk提供类的使用说明】
【 jdk api 1.8_google.CHM
一,CHM文件下载
链接: https://pan.baidu.com/s/1HBKhPRqONOlUDszt_eGK8w 提取码: wk4g
二,在线下载地址
https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html
三,在线浏览地址
https://docs.oracle.com/javase/8/docs/api/?xd_co_f=47c934d9-e663-4eba-819c-b726fc2d0847】
十七、接口
{ 加 “[]" 的都是可以省略的。}
在Java9+版本中,接口的内容可以有:
1、成员变量其实是常量,格式:
[public] [static] [final] 数据类型常量名称=数据值;
【注意:
常量必须进行赋值,而且一旦赋值不能改变。
常量名称完全大写,用下划线进行分隔。】
2、接口中最重要的就是抽象方法,格式:
[public] [abstract]返回值类型 方法名称(参数列表);
【注意:实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类。】
3、从Java8开始,接口里允许定义默认方法,格式:
[public] default 返回值类型 方法名称 (参数列表) {方法体}
【注意:默认方法也可以被覆盖重写】
4、从Java8开始,接口里允许定义静态方法,格式:
[public] static 返回值类型 方法名称(参数列表) {方法体}
【注意:应该通过接口名称进行调用,不能通过实现类对象调用接口静态方法】
5、从Java9开始,接口里允许定义私有很乏,格式:
普通私有方法: private返回值类型方法名称(参数列表){方法体}
静态私有方法: privatestatic 返回值类型方法名称(参数列表){方法体}
【注意:private的方法只有接口自己才能调用,不能被实现类或别人使用。】
【杂乱知识点】
1、JAVA开发环境、JAVA运行环境、JAVA虚拟机
【jdk、jre、jvm】
2、运行JavaApplication应用程序,我们只需要安装JRE即可
3、windows操作系统下,如果希望在任意路径下都能使用JAVA开发环境的编译和运行等命令,需要配置的环境变量是 path
4、为了遵循归一原则,以及方便引用,如果需要修改JDK的安装目录时,修改一处,避免每次引入较长jdk目录时,需要配置的环境变量是什么?有时,根据第三方软件引用规范,也会配置该变量,例如Tomcat。:JAVA_HOME
5、你编译一个JAVA程序—A.java, 会得到一个A.class的类文件,你在当前目录下执行java A, 将会得到相应的结果. 现在, 你把A.class移到别的目录下(例如:“e:”), 执行java A, 将会有NoClassDefFindError的异常,原因就是找不到.class文件,可以通过配置哪个环境变量解决该问题。:CLASSPATH
6、谈谈你对Java平台的理解?
Java 本身是一种面向对象的语言,最显著的特性有两个方面,
一、是所谓的**“书写一次,到处运行”(Write once, run anywhere)**,能够非常容易地获得跨平台能力;
二、就是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
我们日常会接触到 **JRE(Java Runtime Environment)**或者 JDK(Java Development Kit)。 JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。
对于*“Java 是解释执行”*这句话,这个说法不太准确。我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK 提供的 Hotspot JVM,都提供了 **JIT(Just-In-Time)**编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。
知识扩展
知识扩展回归正题,对于 Java 平台的理解,可以从很多方面简明扼要地谈一下,例如:Java 语言特性,包括泛型、Lambda 等语言特性;基础类库,包括集合、IO/NIO、网络、并发、安全等基础类库。对于我们日常工作应用较多的类库,面试前可以系统化总结一下,有助于临场发挥。
或者谈谈 JVM 的一些基础概念和机制,比如 Java 的类加载机制,常用版本 JDK(如 JDK 8)内嵌的 Class-Loader,例如 Bootstrap、 Application 和 Extension Class-loader;类加载大致过程:加载、验证、链接、初始化(这里参考了周志明的《深入理解 Java 虚拟机》,非常棒的 JVM 上手书籍);自定义 Class-Loader 等。还有垃圾收集的基本原理,最常见的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1 等,对于适用于什么样的工作负载最好也心里有数。这些都是可以扩展开的领域,我会在后面的专栏对此进行更系统的介绍。
当然还有 JDK 包含哪些工具或者 Java 领域内其他工具等,如编译器、运行时环境、安全工具、诊断和监控工具等。这些基本工具是日常工作效率的保证,对于我们工作在其他语言平台上,同样有所帮助,很多都是触类旁通的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qD4xeH31-1628557971541)(D:\CTF资料\靶场收获资料\java平台.jpg)]
7、抽象类和接口
1.抽象类是什么
抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性。
(1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法
(2) 抽象类不能被实例化
(3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类
(4) 具体派生类必须覆盖基类的抽象方法
(5) 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必须覆盖它们
2.接口是什么
(1) 接口不能被实例化
(2) 接口只能包含方法声明
(3) 接口的成员包括方法、属性、索引器、事件
(4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员
3.接口和抽象类的区别
(1)抽象类可以有构造方法,接口中不能有构造方法。
(2)抽象类中可以有普通成员变量,接口中没有普通成员变量
(3)抽象类中可以包含静态方法,接口中不能包含静态方法
(4) 一个类可以实现多个接口,但只能继承一个抽象类。
(5)接口可以被多重实现,抽象类只能被单一继承
(6)如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
4.接口和抽象类的相同点
(1) 都可以被继承
(2) 都不能被实例化
(3) 都可以包含方法声明
(4) 派生类必须实现未实现的方法
M 上手书籍);自定义 Class-Loader 等。还有垃圾收集的基本原理,最常见的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1 等,对于适用于什么样的工作负载最好也心里有数。这些都是可以扩展开的领域,我会在后面的专栏对此进行更系统的介绍。
当然还有 JDK 包含哪些工具或者 Java 领域内其他工具等,如编译器、运行时环境、安全工具、诊断和监控工具等。这些基本工具是日常工作效率的保证,对于我们工作在其他语言平台上,同样有所帮助,很多都是触类旁通的。
[外链图片转存中…(img-qD4xeH31-1628557971541)]
7、抽象类和接口
1.抽象类是什么
抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性。
(1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法
(2) 抽象类不能被实例化
(3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类
(4) 具体派生类必须覆盖基类的抽象方法
(5) 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必须覆盖它们
2.接口是什么
(1) 接口不能被实例化
(2) 接口只能包含方法声明
(3) 接口的成员包括方法、属性、索引器、事件
(4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员
3.接口和抽象类的区别
(1)抽象类可以有构造方法,接口中不能有构造方法。
(2)抽象类中可以有普通成员变量,接口中没有普通成员变量
(3)抽象类中可以包含静态方法,接口中不能包含静态方法
(4) 一个类可以实现多个接口,但只能继承一个抽象类。
(5)接口可以被多重实现,抽象类只能被单一继承
(6)如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
4.接口和抽象类的相同点
(1) 都可以被继承
(2) 都不能被实例化
(3) 都可以包含方法声明
(4) 派生类必须实现未实现的方法