Java Web知识点概括
前言
1.JDK、JRE、JVM之间的区别和联系
- JDK是Java开发工具包,JRE是Java运行环境,JVM是Java虚拟机
- 这三者关系是嵌套的,JDK包含了JRE,JRE包含了JVM
一、static关键字
1.Static是在类中最先被(JVM机制)加载
2.作用:
(1)创建独立于具体对象的域变量或方法
(2)可以不创建对象,也能直接使用属性和调用方法定义的顺序
(3)形成静态代码块用来优化程序性能
3.加载顺序
(1)类在初次加载时,会按照static块来执行,且只会执行一次
4.Static独特的作用,被static修饰的变量或者方法独立于该类的任何对象,被类的实例对象共享,内存中只有一个副本
5.注
(1)在类的第一次使用时加载并初始化,后面科根据需要赋值
(2)Static不允许用来修饰局部变量
6.与普通变量的区别
(1)Static:static成员变量的初始化顺序按照定义的顺序进行初始化
(2)非static是对象所拥有的的,子创建对象的时候被初始化,存在多个副本,各个对象拥有的副本各不影响
7.静态内部类
(1)不能使用任何外围类的非static成员变量和方法
(2)当前类加载的时候,静态内部类没有被加载进内存。只有调用静态内部类才能出发静态内部类才会加载和初始化,请JVM机制会确保只能实例化一次,JVM提供了线程安全的支持
8.静态导包—import static
(1)可导入某个类中的指定静态资源
(2)可不使用类名调用类中的静态变量就直接使用(但是开发不建议这样做)
9.Static与final
二、抽象类和接口
1、抽象类(abstract)
- 抽象类和类一样拥有构造方法、static静态修饰成分
1、抽象类可无抽象方法
2、抽象类的构造方法不能直接用来创建对象实例
3、抽象类不能用final、private修饰,访问类型为public、protected
4、外部抽象类不能用static修饰,但是内部抽象类可以使用static声明,如下
abstract class A{ static abstract class B{ public abstract void decise(); } }
- 抽象方法
1、抽象方法没有方法体
2、抽象方法必须用abstract关键字修饰
3、抽象方法必须为public和protected,缺省默认public
4、抽象方法的类一定是抽象类,普通方法也可在抽象类 - 意义
1、抽象类定义就是为了继承
2、抽象类的构造方法不能直接被实例化,要创建对象涉及向上转型,作用是为了被子类调用
3、普通类继承抽象类一定要实现抽象父类的抽象方法,如果没有实现,需要子类也定义为抽象类
2、接口(interface)
-
基本概念
1、接口中的方法默认为public abstract类型- 1但是也有特例,如下
interface A{default void b(){System.out.println("default方法");}}
2、接口中的成员变量类型默认且只能为public static final(可略)变量类型
3、接口中不能有构造方法
4、接口中的方法被隐式的指定且只能为public abstract方法
5、接口可以实现多继承,用逗号隔开即可
3、抽象类和接口的区别
-
设计思想
1、抽象类添加新的发,可以直接在抽象类中添加具体的实现(类似普通方法),子类可不变更
2、接口进行了变更,所有实现这个接口的类都需要相应的改动 -
设计角度
1、抽象类是对整个类进行抽象,包括属性、行为
2、接口是对行为的抽象,是对局部行为的抽象
三、继承
1.继承
- 继承是子类继承父类的属性和行为,子类可以直接访问父类中非私有的属性和行为
- 提高代码的复用性,使类与类产生了关系
- 只支持单继承不支持多继承
2.成员变量
- 如果成员变量不重名,在子类调用父类对象可直接调用
- 如果成员变量重名的话,访问父类成员变量需要使用super.父类成员变量名,this.子类成员变量名
3.如何访问父类私有成员变量
- 非私有的变量可以直接访问
- 私有的变量使用封装的方法get和set访问即可
4.成员方法
- 如果成员方法不重名,在子类调用父类对象可直接调用,因为对象在调用方法的时候,会先在子类中查找有没有对应的方法,如果子类中存在就先执行之类的方法,若子类中不存在就执行父类中相应的方法
- 如果成员方法重名的话
1、方法名相同,返回值类型、参数列表却不相同(先在子类查找,子类无再去父类查找)
2、方法名和返回值类型、参数列表都相同,则重写(Override)方法
5.重写的意义
- 继承了父类的功能和可以根据子类的需要进行扩展
- 重写的时候加上super.父类方法();表示调用父类成员方法
6.重写需要注意的
- 重写必须方法名和形参列表一致
- 子类方法覆盖父类方法,子类的权限要大于等于父类权限
- 重写方法时子类的返回类型要小于等于父类的返回值类型,子类抛出的异常类型要小于等于父类抛出的异常类型
7.构造方法
1.如果在main方法中实例化了子类对象,接着会去执行子类的默认构造器初始化,这个时候在构造方法中默认第一句代码中添加super(),不写这个也存在,且必须在第一句代码里
2. 构造方法的作用是初始化成员变量,在子类的初始化过程中,必须先执行父类的初始化动作,所以子类的构造方法中默认第一句添加super();表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用
class Father {
// 父类的无参构造方法。
public Father(){
System.out.println("父类构造方法执行");
}
}
class Son extends Father {
// 子类的无参构造方法。
public Son(){
System.out.println("子类构造方法执行了");
}
}
public class ConstructionDemo {
public static void main(String[] args) {
// 创建子类对象
Son s = new Son();
}
}
//结果是
//父类构造方法执行
//子类构造方法执行了
8.super和this的用法
- 1、super :代表父类的存储空间标识(可以理解为父亲的引用)。
- 2、this :代表当前对象的引用(谁调用就代表谁)
- 3、super和this不能同时出现在一个构造函数里面,因为this必然会调用其它构造函数,其它构造函数会有super语句的存在,且都必须在构造方法的第一行。
9.继承的多态性
四、重载和重写
-
重载(overload)的规则
- 必须具有不同的参数列表
- 与返回值无关
- 可以有不同的访问修饰符
- 可以抛出不同的异常
- 方法能够在一个类中或者在一个子类中被重载。
- 存在于父类、子类和同类中
-
重载的意义
- 算是一种另类的if else,比if else要写的代码更加少,参数传递更加明确,有利于团队的开发
- 输入不同,输出相同的时候,一般可能会用到重载
-
重写(override)的规则
- 方法名、参数、返回值相同
- 子类方法不能缩小父类方法的访问权限
- 子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)
- 存在于父类和子类之间
- 方法被定义为final不能被重写。
-
重写的意义
- 子类对父类的方法进行扩展
-
重载和重写的区别
·1. 方法的重写Override和重载Overload是Java多态性的不同表现。重写Override是父类与子类之间多态性的一种表现,重载Overload是一个类中多态性的一种表现2.方法重载是指在同一个类中,多个方法名相同,他们的参数列表不同。方法重写是指子类和父类中方法相同,两个类之间的关系
五、重写toString方法
- 为什么要重写toString方法
1. toString()方法是在Object类里面的方法,它返回的是String型的数据:类名+@+哈希值的16进制形式
2. 直接打印对象的引用,会默认调用toString()方法
Student stu = new Student("Jack",18);
System.out.println(stu);
- 如何重写toString方法
1.使用快捷键Alt+Shift+S,点击Override,选择toString()方法
2.在Student类里面按Alt+Shift+S,点击Generate toString()方法
public String toString() {
return super.toString();
}
//法1
public String toString() {
return "我的名字是" + name + "年龄是" + age;
}
//法2
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
六、多态
1、基本概念
- 程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而在程序运行期间才确定
- 多态指的是同一行为,具有多个不同表现形式
2、多态的前提
- 继承或者实现
- 方法重写
- 父类引用子类对象(向上转型)
3、多态的调用
-
使用多态调用方法时,先检查父类中是否有该方法,如果父类没有,编译错误。
-
如果父类有,则执行子类重写父类的方法(即向上转型)
- 为什么有些子类没有重写这个方法,但是仍然执行,因为虽然子类没有写出来,但是他继承了父类这个方法,只是没有明确的写出来,所以实际中调用的是子类中的继承父类的方法,super();没有写但是在
class Father{
public void fu(){
System.out.println("Father");
}
}
class Sun extends Father{
public void sun(){
System.out.println("sun");
}
}
public class Test {
public static void main(String[] args) {
Father f=new Sun();
f.fu();
}
//运行结果:Father
}
4、多态的动态和静态绑定
- 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来,就是一个方法调用另一个方法
- 静态绑定(前期绑定),就是程序编译期的绑定,Java的方法中只有final,static,private(不会被继承)和构造方法是静态绑定的,使用的是类信息
- 动态绑定(后期绑定),在运行时根据具体对象的类型进行绑定,使用的是对象信息
5、向上转型和向下转型
- 向上转型
Father father = new Son();
父类指向子类的引用
作用:减少代码的重复 - 向下转型
Son s =(Son) father;
作用:为什么要有向下转型,使用多态调用方法的时候,先检查父类中是否有该方法,如无则编译错误,就是说多态不能调用子类拥有而父类没有的办法,如果想要调用子类独有的方法,就要做向下转型
6、instanceof判断数据类型
- 概念:如果变量属于该数据类型则返回true,否则返回false
- 作用:两个都继承这个父类的子类有同名方法,如果不做判断,数据类型会报错
七、泛型(Generic)
- 基础概念
- 集合是可以存放任何对象的,放入集合后自动转化为object类型,所以此每次取出一个对象都要进行类型转换
- 但是如果在集合里存储如多种对象,程序就会在运行时发生Java.lang.ClassCastException异常,因为实际上Collection只存储同一类型对象
- 关键词
- E(Element)在集合中使用,因为集合中存放的是元素
- T(Type)T表示在调用时的指定类型
- K(key键)
- V(Value值)
- N(Number)数值类型
- ?表示不确定的Java类型,一般在通配的时候使用
八、进程、线程、多线程
- 进程概念
- 进程是系统中正在运行的一个程序,程序一旦运行就是进程,
- 进程是系统资源分配的独立实体,每个进程拥有独立的地址空间
- 如果一个进程要访问另一个进程的资源,需要使用进程间通信
- 一个进程可以拥有多个线程
- 线程概念
- 每个线程使用其所属进程的栈空间
- 线程是进程的一个实体,是进程的一条执行路劲
- 线程是进程的一个特定执行路劲,当一个线程修改了进程的资源,他的兄弟线程可以立即看到这种变化
- 多线程
- 多线程是指一个进程运行时产生了多个线程
- 并行与并发
- 并行:多个CPU实例或者多台机器同时执行一段处理逻辑
- 并发:通过CPU调度算法,让用户看着像同时执行,但是CPU上是平法使用公用的资源
- 会出现的问题
- 线程安全:这意味着线程的调度顺序会影响最终结果
- 同步:是指人为的控制和调度,保证共享资源的多线程访问称为线程安全,来保证结果的准确
- 死锁
九、异常
1、概念
1.1、异常原因
程序的运行只考虑到正常情况,出现了一些不正常运行,导致程序中断
1.2、解决方案:
程序员可以修改代码、用户无法修改代码可以使用用户异常处理机制,处理完毕后,程序就可以正常运行。
2、异常处理的5个关键字
2.1、try:执行可能产生异常的代码(必写的,但是不能单写,必须配一个catch或者finally)
2.2、catch:捕获异常-处理异常(可不写),可以使用多重catch
使用规则:
排列catch语句的顺序,先子类后父类
发生异常时按顺序逐个匹配
只执行第一个与异常类型匹配的catch语句
2.3、finally:无论代码是否发生异常,代码总能执行(可不写)
唯一不执行finally的情况是System.exit(1);//表示中断程序,退出Java虚拟机
try{
}catch(异常){
}finally{
}
2.4、throws:声明异常,告诉你方法抛出了异常,但是没有能力处理这个异常,希望调用这个方法的人处理这个异常,如果别人也不会处理这个异常,可以继续抛出异常(使用逗号隔开)。
如果继续抛下去,回事main方法处理异常,main方法也不回,虚拟机会处理异常
public void divide() throws Arith~,~{}
//把异常抛给处理机
public static void main (String[] args)throws Arith~,~{
t.divide();
}
//在程序使用try处理掉异常
public static void main (String[] args){
try{
t.divide();
}catch(){}
}
2.5、throw(真正的抛出去):在代码里用throw生成了一个异常,后面必须处理掉,或者使用throws抛出异常
public class Person{
private String name;
private int age;
private Sring sex;
//省略set和get方法
public void setSex(String sex) throws Exception{
if(sex.equals("男“)||sex.equals("女")){
this.sex=sex;}
}else{
//如果不是男女,就抛出一个异常
//写法一
Exception e= new Exception("性别只能为男女!");
throw e;
//写法二,抛出异常,没必要再声明一个对象
throw new Exception("性别只能为男女!");
//但是这里抛出的异常,必须处理或者(在方法里声明throws Exception)告诉别人
}
public void print(){
System.out.println(this.getName()+"-"+this.getSex()+"-"+this.getAge();)}
}
public static void main(String[] args){
Person p=new Person();
p.setSex("boy");//这里会直接报错,所以直接在这里处理掉
//如下处理
try{
p.setSex("boy");}
catch(Exception e){
e.printStackTrace();
}
2.6、throw和throws的区别