虽然说框架满天飞,但打好地基很重要,整理一下基础知识,以备不时之需,毕竟好记性不如烂笔头,常回来看看老朋友。。。
Java的数据类型
- 基本类型:long,int,byte,float,double,char
- 对象类型(类): Long,Integer,Byte,Float,Double,String,其它一切java提供的,或者你自己创建的类。引用类型比较大小一定要用equals而不要用==。
基本数据类型的封装类
数据类型 | 封装类/包装类 |
---|---|
boolean(布尔型) | Boolean |
byte(字节型) | Byte |
char(字符型) | Character |
short(短整型) | Short |
int(整型) | Integer |
long(长整型) | Long |
float(浮点型) | Float |
double(双精度浮点型) | Double |
什么叫包装类
在java中有时候的运算必须是两个类对象之间进行的,不充许对象与数字之间进行运算。所以需要有一个对象,这个对象把数字进行了一下包装,这样这个对象就可以和另一个对象进行运算了。byte: 八位整数 -128——127,可用来节省内存的使用。
short: 16位整数 -32768——32,767,也比较省内存。
int: 32位整数 -2,147,483,648——2,147,483,647,一般来说整数都够用了
long: 64位整数 -9,223,372,036,854,775,808—— 9,223,372,036,854,775,807,一般不需要用
float: 32位浮点,如果浮点需要节省内存用这个。
Double: 64位浮点,一般非整数浮点可用这个。
但是要记住float和double都不是精确的,如果要储存钱一类的必须精确的,用java.math.BigDecimal
为什么要有包装类(或封装类)?
为了使基本数据类型的变量具有类的特征,引入包装类。
参数类型和返回值类型
一个方法的返回值类型要是抽象类类型,那么就返回该抽象类的子类对象。
一个方法的返回值类型要是接口类型,那么就返回该接口类的子类对象。
变量的定义
局部变量:从属于方法或语句块,生命周期短,使用前必须先初始化赋值。
成员变量:从属于对象,生命周期较长,未赋值会自动被初始化。
静态变量:从属于类,生命周期最长。
在类中,使用static修饰的成员变量被称为静态成员变量(类变量)。
static修饰的变量和方法从属于类,普通变量和方法从属于对象的。
Java中主要用final来定义一个常量。Final String AGE=18相当于age=18,常量都是大写,所以是AGE;
定义方法时传递的参数是形式参数,调用该方法时传递的参数是实际参数,实参的数据类型必须与形参一一对应。
用static修饰方法的好坏
在定义方法时不加static,在调用方法时就需要new该方法才能调用,如果在定义时加上static,就可以直接调用该方法而不需要new了。
好处:
1.当一个方法需要初始化加载或者经常被调用的时候可以加上 static
2.被 static 修饰的方法可以用类名直接调用,不用实例化一个对象后才调用
3.比如 person这个类里有一个方法 public static add () {} 那么可以使用 person.add();调用,当然也可以创建对象调用
比如 person p= new person();
p.add();调用
类加载器在加载这个类的时候就已经实例化了这个类
坏处:初始化加载比较占内存,所以不经常用的方法不建议加 static 这个关键字
public static void main(String[] args)
这是 Java 程序的入口地址,Java 虚拟机运行程序的时候首先找的就是 main 方法。跟 C 语言里面的 main() 函数的作用是一样的。只有有 main() 方法的 Java 程序才能够被 Java 虚拟机运行,可理解为规定的格式。
对于里面的参数及修饰符:
- public :表示的这个程序的访问权限,表示的是任何的场合可以被引用,这样 Java 虚拟机就可以找到 main() 方法,从而来运行 javac 程序。
- static : 表明方法是静态的,不依赖类的对象的,是属于类的,在类加载的时候 main() 方法也随着加载到内存中去。由于在入口时,未调用任何对象,该方法只能设置为static静态。
- void: main()方法是不需要返回值的。JVM为Java的最底层,所以即使有返回结果,结果也无处可去,因此该方法必然是void无返回值。
- main :约定俗成,规定的。
- String[] args :从控制台接收参数。
标识符
1、标识符的使用:凡是自己可以起名字的地方都叫标识符。比如:类名、变量名、方法名、接口名、包名等等。。。
2、标识符的命名规则:
- 由26个英文字母大小写,0-9,_或$组成
- 数字不可以开头
- 不可以使用关键字和保留字,但能包含关键字和保留字
- Java中严格区分大小写,长度无限制
- 标识符不能包含空格
Java中的名称命名规范
包名:多个单词组成时所有字母都小写:xxxyyyzzz
类名、接口名:多个单词组成时,所有单词的首字母大写:XxxYyyZzz
变量名、方法名:多个单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
常量名:所有字母都大写,多个单词组成时每个单词用下划线连接:XXX_YYY_ZZZ
基本数据类型
自动类型提升
结论:当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型(不包含boolean类型)
byte、char、short–>int–>long–>float–>double
特别的:当byte、char、short三种类型的变量做运算时,结果为int型。
强制类型转换
自动类型提升运算的逆运算。
1、需要使用强转符:()
2、注意点:强制类型转换,可能导致精度降低或溢出。
String字符串
- String属于引用数据类型,翻译为:字符串
- 声明String类型变量时,使用一对””
3.String可以和8种基本数据类型变量做运算,且运算符只能是连接运算:+
4.运算的结果仍然是String类型
逻辑运算符
逻辑运算符操作的都是boolean类型的变量
区分&和&&
相同点1:运算结果都相同
相同点2:当符号左边是true时,二者都会执行符号右边的运算
不同点:当符号左边是false时,&继续执行符号右边的运算,&&则不再执行符号右边的运算。
位运算符
1.位运算符操作的都是整型的数据
2.<<:在一定范围内,每向左移1位,相当于 * 2;
>>:在一定范围内,每向右移1位,相当于 / 2;
程序流程控制
- 顺序结构、分支结构、循环结构
分支结构
Switch-case
- Switch结构中的表达式,只能是如下6种数据类型之一:byte、short、char、int、枚举类型(JDK5.0新增)、Sting类型(JDK7.0新增)
- case之后只能声明常量,不能声明范围
- break关键字是可选的
- default:相当于if-else结构中的else,default结构是可选的,而且位置也是灵活的。
switch-case和if-else怎么选
总结:
- 凡是可以使用Switch-case的结构,都可以转换为if-else;反之,不成立;
- 我们写分支结构时,当发现既可以使用Switch-case(同时,Switch中表达式的取值情况不太多),又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
循环结构
定义:在某些条件满足的情况下,反复执行特定代码的功能。
循环语句分类:
- for循环
- while循环
- do-while循环
循环语句的四个组成部分
- 初始化部分
- 循环条件部分
- 循环体部分
- 迭代部分
衡量一个功能代码的优劣
- 正确性
- 可读性
- 健壮性
- 高效率与低存储:时间复杂度和空间复杂度(衡量算法的好坏)
数组
定义:数组是一种数据结构,它由一组相同类型的元素组成,这些元素在内存中连续存储,并可以通过索引(下标)访问和修改。
数组中常见的算法
排序算法
衡量排序算法的优劣:
- 时间复杂度:分析关键字的比较次数和记录的移动次数
- 空间复杂度:分析排序算法中需要多少辅助内存
- 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
排序算法的分类:
内部排序和外部排序。
- 内部排序:整个排序过程中不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。
- 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路 归并排序,可以认为外部排序是由多次内部排序组成。
十大内部排序算法:
- 选择排序
- 直接选择排序、堆排序
- 交换排序
- 冒泡排序、快速排序
- 插入排序
- 直接插入排序、折半插入排序、Shell排序
- 归并排序
- 桶式排序
- 基数排序
JVM的内存结构
在JVM中,有几个重要的概念和组件,包括栈、堆、常量池、方法区和静态域。
栈(Stack)
栈是一种基于后进先出(LIFO)的数据结构,用于存储方法调用的相关信息,如方法的参数、局部变量、返回地址等。在 Java 中,每个线程都有自己的栈,用于存储该线程的方法调用信息。当一个方法被调用时,会在栈上分配一块新的内存空间,用于存储该方法的参数和局部变量。当方法执行完毕时,这个内存空间会被释放。
举例来说,以下是一个简单的 Java 方法:
1 | public void method(int a, int b) { |
当这个方法被调用时,在该方法的栈上会分配一些内存空间,用于存储参数 a 和 b,以及局部变量 sum。当方法执行完毕时,这些内存空间会被释放。
堆(Heap)
堆是一种用于动态分配对象的内存区域。在 Java 中,所有的对象都在堆上分配内存。堆是一块共享的内存区域,所有线程都可以访问。当创建一个对象时,会在堆上分配一块新的内存空间,用于存储对象的数据。
举例来说,以下是一个简单的 Java 类:
1 | public class Person { |
当创建一个 Person 对象时,会在堆上分配一块新的内存空间,用于存储对象的数据。在这个例子中,Person 对象会包含一个 String 类型的 name 属性和一个 int类型的 age 属性。
1 | Person p = new Person("John", 30); |
在这个例子中,p 是一个 Person 类型的对象,它被创建在堆上,并分配了一块内存空间来存储对象的数据。
常量池(Constant Pool)
常量池是一种特殊的内存区域,用于存储常量和符号引用。在 Java 中,常量池主要用于存储字符串常量、数字常量和类、方法、字段等符号引用信息。
举例来说,以下是一个包含字符串常量和符号引用的 Java 类:
1 | public class Constants { |
在这个例子中,字符串常量 “Hello, world!” 和整数常量 100 会被存储在常量池中。同时,静态常量 MESSAGE 和 SIZE 也会被存储在常量池中,它们的值是对常量池中字符串和数字常量的引用。当 main 方法被调用时,会从常量池中获取 MESSAGE 的值,并输出到控制台。
方法区(Method Area)
方法区是一种用于存储类信息、常量池、静态变量等数据的内存区域。在 Java 中,每个类都有自己的方法区,用于存储类的信息和静态成员变量。方法区是堆的一部分,但是它有自己的内存管理机制。
举例来说,以下是一个包含静态变量的 Java 类:
1 | public class Counter { |
在这个例子中,静态变量 count 会被存储在方法区中,它的值在整个应用程序的生命周期内都是可见和共享的。当 increment 方法被调用时,会从方法区中获取 count 的值,并将其加 1。当 getCount 方法被调用时,也会从方法区中获取 count 的值并返回。
静态域(Static Field)
静态域是一种类级别的变量,它属于类而不属于对象。在 Java 中,静态域可以被所有对象共享,也可以被类的所有方法访问。静态域通常用于存储类级别的信息和常量。
举例来说,以下是一个包含静态域的 Java 类:
1 | public class MathUtils { |
在这个例子中,静态域 PI 存储了圆周率的值,它可以被 MathUtils 类的所有方法访问。当 circleArea 方法被调用时,会从静态域 PI 中获取圆周率的值,并进行计算。
需要注意的是,栈、堆、常量池、方法区和静态域是 Java 运行时的重要组成部分,它们的实现和使用方式可能与不同的 Java 实现和版本有所不同。
小结
虚拟机栈,即为平时提到的栈机构。方法的参数和局部变量都存储在栈结构中。
堆:将new出来的结构(比如:数组、对象)加载到堆空间中。补充:对象的属性(非static的)加载在堆空间中。
方法区:类的加载信息、常量池、静态域
面向对象
思想概述
面向对象:把属性(成员变量)和方法放入一个类里面,类里面抽象出来共同点就是面向对象。
面向对象的两个要素:
类:对一类事物的描述,是抽象的、概念上的定义。
对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)
- 面向对象程序设计的重点是类的设计
- 设计类,就是设计类的成员
类中属性的使用
属性(成员变量)VS局部变量
1.相同点
1.1 定义变量的格式:数据类型 变量名 =变量值
1.2 先声明,后使用
1.3 变量都有其对应的作用域
2.不同点:
2.1在类中毒声明的位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.2 关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected —>封装性
目前,大家声明属性时,都使用缺省即可。
局部变量:不可以使用权限修饰符
2.3 默认初始值的情况
属性:类的属性,根据其类型,都有默认初始化值
局部变量:没有默认初始化值。
意味着,我们调用局部变量之前,一定要显式赋值。
特别的,形参在调用时,我们赋值即可。
2.4 在内存中加载的位置
属性:加载到堆空间中(非static)
局部变量:加载到栈空间
小结
1.面向对象思想编程内容的三条主线分别是什么:
①类及类的成员:属性、方法、构造器、代码块、内部类
②面向对象的三大特征:封装、继承、多态
③其它关键字:this、super、abstract、interface、static、final、package、import
2.谈谈你对面向对象中类和对象的理解,并指出二者的关系?
类:抽象的、概念上的内容
对象:实实在在的一个个体。对象是由类派生出来的。
3.面向对象思想的体现一:类和对象的创建和执行操作由哪三步?
① 创建类
② 类的实例化
③ 调用对象的结构:”对象.属性” “对象.方法”
匿名对象的使用
- 理解:我们创建的对象,没有显式的赋给一个变量名,即为匿名对象
- 特征:匿名对象只能调用一次
面向对象与面向过程(理解)
1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
递归方法:自己调用自己,但要写递归头和递归体,否则陷入死循环,直到占满内容溢出为止。递归是很耗费时间和内存资源的,尽量不要使用,百度的爬虫就是递归,在一个页面不断点击进入下一个页面那种,一般使用迭代循环方法就能满足普通开发。
方法重写(Override)与重载(Overload)
方法重载:参数的个数、类型和顺序不同,都可以构成重载。方法中参数只有返回值不同、参数只有名称不同,都不构成重载。(跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!)
1 | * 方法的重载(overload) loading…… |
方法重写:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖、在程序执行时,子类的方法将覆盖父类的方法。
1 | * 方法的重写(override/overwrite) |
Java的值传递机制
关于变量的赋值
- 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
- 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
针对于方法的参数概念
形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给形参的数据
Java中参数传递机制
值传递规则
- 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
- 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
封装和隐藏
我们程序设计追求“高内聚,低耦合”。
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉。
- 低耦合:仅对外暴露少量的方法用于使用。
封装性的体现方式
- 将类的属性私有化(private),同时,提供公共的(public)方法来获取(getXXX)和设置(setXXX)此属性的值.
- 不对外暴露的私有方法
- 单例模式(将构造器私有化)
- 如果不希望类在包外被调用,可以将类设置为缺省的。
Java规定的四种权限修饰符:
从小到大顺序为:private<缺省<protected<public
具体修饰范围:
继承性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 * 一、继承性的好处:
* ① 减少了代码的冗余,提高了代码的复用性
* ② 便于功能的拓展
* ③ 为之后多态性的使用,提供了前提
*
* 二、继承性的格式:class A extends B{}
* A:子类、派生类、subclass
* B:父类、超类、基类、superclass
*
* 2.1 体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法
* 特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。
* 只是因为封装性的影响,使得子类不能直接调用父类的结构而已。
*
* 2.2 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
* 子类和父类的关系,不同于子集和集合的关系。
* extends:延展、扩展
*
* 三、Java中关于继承性的规定:
* 1.一个类可以被多个子类继承。
* 2.Java中类的单继承性:一个类只能有一个父类
* 3.子父类是相对的概念
* 4.子类直接继承的父类,称为:直接父类。间接继承的父类,称为:间接父类
* 5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法。
*
* 四、1.如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
* 2.所有的java类(除java.lang.Object类之外)都直接或间接继承于java.lang.Object类。
* 3.意味着,所有的java类具有java.lang.Object类声明的功能。
多态性
1.理解多态性:可以理解为一个事物的多种形态。
2.何为多态性:
对象的多态性:父类的引用指向子类对象(或子类的对象赋给父类的引用)
3.多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译,看左边,运行,看右边。
4.多态性的使用前提:① 类的继承关系 ② 方法的重写
5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法。父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
从编译和运行角度
对于重载而言:在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”
而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。
Instanceof关键字的使用
构造器
1.通过new关键字调用。
2.构造器有返回值,但不能定义返回值类型,即可以return,但不能返回值。
3.如果我们没有定义一个构造器,编译器会自动定义一个无参的构造函数。
4.构造方法名字必须要与类名相同。
构造器的作用
- 创建对象
- 初始化对象的信息
说明
- 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
- 定义构造器的格式:权限修饰符 类名(形参列表){}
- 一个类中定义的多个构造器,彼此构成重载
- 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
- 一个类中,至少会有一个构造器
this和super关键字
调用构造器注意点:
this(形参列表):本类重载的其它的构造器
super(形参列表):调用父类中指定的构造器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 * super关键字的使用
* 1.super理解为:父类的
* 2.super可以用来调用:属性、方法、构造器
*
* 3.super的使用
* 3.1 我们可以在子类的方法或构造器中。通过使用“super.属性”或“super.方法”的方式,显式的调用
* 父类中声明的属性和方法。但是,通常情况下,我们习惯省略"super."
* 3.2 特殊情况,当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,
* 则必须显式的使用“super.属性”的方式,表明调用的是父类中声明的属性。
* 3.3 当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的
* 使用“super.方法”的方式,表明调用的是父类中被重写的方法。
*
* 4.super调用构造器
* 4.1 我们可以在子类的构造器中显式的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器
* 4.2 “super(形参列表)”的使用,必须声明在子类构造器的首行!
* 4.3 我们在类的构造器中,针对于“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现
* 4.4 在构造器的首行,没有显示的声明“this(形参列表)”或“super(形参列表)”,则默认调用的是父类中
* 空参的构造器:super()
* 4.5 在类的多个构造器中,至少有一个类的构造器中使用了“super(形参列表)”,调用父类中的构造器
JavaBean的使用
描述:JavaBean是一种Java语言写成的可重用组件。
所谓JavaBean,是值符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
MVC设计模式
DeBug调试
==和equals()的区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 * 一、回顾==的使用:
* ==:运算符
* 1.可以使用在基本数据类型变量和引用数据类型变量中
* 2.如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)
* 如果比较的是引用数据类型变量:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
* 补充:==符号使用时,必须保证符号左右两边的变量类型一致。
*
* 二、equals()方法的使用:
* 1.是一个方法,而非运算符
* 2.只能适用于引用数据类型
* 3.Object类中equals()的定义:
* public boolean equals(Object obj) {
* return (this == obj);
* }
* 说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
*
* 4.像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是
* 两个引用的地址是否相同,而是比较的两个对象的“实体内容”是否相同。
*
* 5.通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的“实体内容”是否相同。
* 那么,我们就需要对Object类中的equals()进行重写
* 重写的原则:比较两个对象的实体内容是否相同。
设计模式
概念:设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。
单例设计模式
要解决的问题:所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
饿汉式:
- 坏处:对象加载时间过长,会造成资源的浪费。
- 好处:是线程安全的。
代码示例:
1 | //饿汉式 |
懒汉式:
- 坏处:非线程安全,实现相对复杂,需要考虑线程安全性和性能等问题,需要额外的代码来处理。
- 好处:延迟加载对象,避免资源的浪费。
代码示例:
1 | //懒汉式 |
单例模式的优点:减少了系统性能的开销。
应用场景:
- 网站的计数器
- 应用程序的日志应用
- 数据库连接池
- 读取配置文件的类
- Application
- Windows的任务管理器、回收站。
static关键字
1 | * 1.static:静态的 |
final关键字
1 | * final:最终的 |
代码块
1 | * 1.代码块的作用:用来初始化类、对象的信息 |
实例化子类对象时,涉及到父类、子类中静态代码块、非静态代码块、构造器的加载顺序总结为:由父及子,静态先行。
abstract抽象类
1 | * abstract关键字的使用 |
interface接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 * 1.接口使用interface来定义
* 2.Java中,接口和类是并列的两个结构
* 3.如何定义接口:定义接口中的成员
* 3.1 JDK7及以前:只能定义全局常量和抽象方法
* >全局常量:public static final的。但是书写时,可以省略不写
* >抽象方法:public abstract的
*
* 3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
*
* 4.接口中不能定义构造器的!意味着接口不可以实例化
*
* 5.Java开发中,接口通过让类去实现(implement)的方式来使用。
* 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
* 如果实现类没有覆盖接口中的所有的抽象方法,则此实现类仍为一个抽象类
*
* 6.Java可以实现多个接口--->弥补了Java单继承的局限性
* 格式:class AA extends BB implements CC,DD,EE
*
* 7.接口与接口之间可以继承,而且可以多继承
*
* ***************************************
* 接口的使用
* 1.接口使用上也满足多态性
* 2.接口:实际上是定义了一种规范
* 3.开发中,体会面向接口编程!
Java8中关于接口的新规范:
//知识点1:接口中定义的静态方法,只能通过接口来调用。
//知识点2:通过实现类的对象,可以调用接口中的默认方法
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明同名同参数的方法,
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。--->类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有重写此方法的情况下,报错。--->接口冲突。
//这就需要我们必须在实现类中重写此方法
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
内部类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 * 1.Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类。
* 2.内部类的分类:成员内部类(静态、非静态) VS 局部内部类(方法内、代码块、构造器内)
* 3.成员内部类:
* 一方面,作为外部类的成员:
* > 调用外部类的结构
* > 可以被static修饰
* > 可以被4种不同的权限修饰
*
* 另一方面,作为一个类:
* >类内可以定义属性、方法、构造器等
* > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
* > 可以被abstract修饰
*
* 4.关注如下的3个问题
* 4.1如何实例化成员内部类的对象
* 4.2如何在成员内部类中区分调用外部类的结构
* 4.3开发中局部内部类的使用:见InnerClassTest1.java
*
*注意点:
*在局部内部类的方法中(比如:show)如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num),要求此局部变量声明为final的。
* jdk 7及之前的版本:要求此局部变量显式的声明为final的
* jdk 8及之后的版本:可以省略final的声明
*
*总结:
*成员内部类和局部内部类,在编译以后,都会生成字节码文件。
*格式:成员内部类:外部类$内部类名.class
* 局部内部类:外部类$数字 内部类名.class
*
异常处理
编译时异常:执行javac.exe命名时,可能出现的异常
运行时异常:执行java.exe命名时,出现的异常
常见的异常
1 | * 一、异常体系结构: |
异常处理的抓抛模型
1 | * 过程一:“抛”:程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。 |
try-catch-finally的使用
1 | * 二、try-catch-finally的使用 |
如何自定义异常类
- 继承与现有的异常结构:RuntimeException、Exception
- 提供全局常量:serialVersionUID
- 提供重载的构造器
会话跟踪技术
1.会话跟踪定义:从进入网站开始到退出网站结束或者关闭浏览器称为一次会话。
2.开始标志:浏览器成功访问页面。
3.结束标志:退出或关闭浏览器。
4.作用:是指在会话过程中多次请求和响应之间共享数据的技术。
5.五种实现会话跟踪方法
5.1URL传参
5.2通过“表单隐藏域”提交
5.3cookie实现
5.4内置对象session实现
5.5内置对象application实现
6.cookie定义:是一小段文本组成的,伴随着用户的请求和服务器的响应,在浏览器和服务器之间来回传递,保存在客户端。
6.1cookie的业务应用:
6.1.1记录上次访问时间
6.1.2猜你喜欢
6.1.3记住用户名
7.session和cookie的区别:
7.1都是用来做会话跟踪
7.2session保存在服务端,cookie保存在客户端
7.3cookie的值只能是String类型,session的值是Object类型
7.4session是内置对象,cookie不是
7.5cookie不安全,session保存在服务端安全性较高
8.内置对象application:
8.1application对象的生命周期从web应用程序启动开始一直到web容器关闭为止。
9.作用域范围
application>session>request>page