java基础知识点(复习一)


Java复习范围

一、 java基础类型,运算符【运算符的优先级顺序】

二、数据结构【链表、set、hash底层原理呀】

三、 基础编程规范【包、类、变量的命名规则】

四、 关键字【使用场景及范围,关键字组合】

五、循环、分支结构,程序运行结果【】

六、面向对象、多态【概念:继承、接口】

七、异常处理【try-catch、error、exception,什么是运行时异常】

八、虚拟机基础知识【垃圾回收、编译的基础流程】

九、 基础框架知识【spring主体框架、mybatis用到的基础知识】


0、其他

  1. 可以使用逗号的是变量初始化的语句,比如int i=1,b=2;

    • 如果是赋值语句,不能用逗号分隔
  2. 只需在代码中加入package java.scut.computer;一个语句,并且必须放在代码的第一行

  3. Java类成员的访问控制权限:

    • public > protected > 同包(default)friendly > private

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png)

  1. abstract只能修饰类和方法 不能修饰字段

  2. 方法是可以和类名同名的,和构造方法唯一的区别就是,构造方法没有返回值。

  3. Ascall码:一个简便的记忆法:0:48 ;A:65 ;a:97,数字连起来是486597 -> 486 597 -> 486 (486 + 111)

  4. 字符串比较优先级:【汉字>英文字母>数字>标点符号】

    • 类型大小:char < short < int < float < double
  5. 只要没有定义任何构造函数,JVM都会为类生成一个默认构造函数。

  6. 计算机所能处理的最小的数据项称为:位

  7. java是面向对象的,但不是所有的都是对象,基本数据类型就不是对象,所以才会有对应的封装类;

  8. 包(package)由一组类(class)和接口(interface)组成

? i. java中"包"的引入的主要原因是java本身跨平台特性的需求。实现跨平台的是JVM。

? ii. package语句是Java源文件的第一条语句。(若缺省该语句,则指定为无名包。),如果想在另一个类里面引用包里面的类,要把名字写全。(相当用文件的绝对路径访问)或者用import导入。

  1. Java中基本的编程单元为:类

  2. 栈是一种存取受限的线性结构

  3. Java语言不支持goto语句

  4. 如何跳出Array的forEach循环? break;return;

  5. 存放位置:

    • 用new创建的对象在堆区
    • 函数中的临时变量在栈去
    • java中的字符串在字符串常量区
    • 静态域:存放在对象中用static定义的静态成员【静态方法运行时所存在是:栈内存】
    • 非RAM存储:硬盘等永久存储空间
  6. 建立一个java.scut.computer的包:只需在代码中加入“package java.scut.computer;”一个语句,并且必须放在代码的第一行。

    • import是用于导包语句,其前面可以出现package,用来声明包的
  7. native是由调用本地方法库(如操作系统底层函数),可以由C,C++实现。

  8. 在同一个java原文件中,可以有多个class类,但是只有有一个公共的 public class。

  9. 观察者属于行为模式

  10. 注解(Annotation)

    • 注解:也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
    • JDK自带注解
      • @Override 表示当前方法覆盖了父类的方法
      • @Deprecation 表示方法已经过时,方法上有横线,使用时会有警告。
      • @SuppviseWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)
  11. java原文件以java结尾,如果类名以public修饰是,文件名与类名必须一致。同一个文件可以有多个类,但是只能有一个直接的public类(内部类可以是public)

  12. java编译命令:javac A.java,编译结果为A.class,字节码文件可以通过javac指令查看

  13. java运行命令:java A,可以通过java指令查看相关的参数

  14. 算法包括0个或多个输入,1个或多个输出,中间有穷个处理过程。

  15. 存储结构不属于算法结构

  16. Equals:

    • Integer s=new Integer(9);Integer t=new Integer(9);Long u=new Long(9);
    • (s.equals(t)) //true
    • (s.equals(9)) //true 在进行equals比较之前,会对9调用Integer.valueOf方法,进行自动装箱
    • (s.equals(new Integer(9)) //true
  17. 局部变量可以与成员变量重名,这时可用“this”来指向成员变量。不加“this”修饰时,优先使用最近的变量。

  18. 一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性

  19. 类中:consInt=constInt+5;【错】

    • 类中定义成员和方法,不能直接进行运算,可以写在代码块{}或者静态代码块中static{}中

二、 java基础数据类型,运算符

  1. 与、或、非:

    • &,或|:(会走完判断条件)
    • 逻辑与&&,逻辑或||:(会短路。简单记忆:“路太长”)
    • 非!:取反
    • 异或:ab不同真假时结果为真;a、b同真或同假时,结果为假
  2. string s=”123”;

? i. s=s+100; //对

? ii. s+=” a”; s+=”a”;//对

? iii. s+=’ b’;//错 ,字符串用双引号

? iv. s=100; //错误,int和string不能互相转换

  1. 三目运算:boolean `b=true?false:true==true?false:true; //false```

? i. == 优先级高于 三目运算符,先判断 true == true,此时返回为 true,

? ii. 这时表达式为 boolean b = true?false:true?false:true

? iii. 此时三目运算符从右向左执行,true?false:true,返回false

? iv. 这时表达式为 boolean b = true?false:false;

? v. 结果为:boolean b = false ;

? vi. 表达式1,表达式2,表达式3的类型可以不同.此时条件表达式的值的类型为它们中较高的类型

  1. 自动装箱、类型转换:

? i. Double d = 100d //对,自动装箱;

? ii. Double d = 100 //错,前面是封装类。

? iii. 而double d=100;//对,这是向上转型

  1. Integer.valueOf方法中也有判断,如果传递的整型变量>= -128并且小于127时会返回IntegerCache类中一个静态数组中的某一个对象, 否则会返回一个新的Integer对象。

? i.

? ii. ![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png)

![img](file:///C:/Users/梦想天1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.png)![img](file:///C:/Users/梦想天1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.png)

  • ①无论如何,Integer与new Integer不会相等。不会经历拆箱过程,
  • ②两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
  • java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
  • ③两个都是new出来的,都为false
  • ④int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比
  1. int x=1;float y=2;x/y=0.5

  2. String s = "hello";String t = "hello";char c [ ] = {'h','e','l','l','o'};t.equals(c)//false 类型不同

  3. String、stringbuild、stringbuffer:

? i. String是个不可继承类(final修饰),也是个不可变类(内部char数组被final修饰)。String是不可变的对象,StringBuffer是可以再编辑的。字符串是常量,StringBuffer是变量。

? ii. StringBuilder , StringBuffer ,String 都是 final 的,但是为什么StringBuilder , StringBuffer可以进行修改呢,因为不可变包括的是,引用不可变以及对象不可变,而这三个都是属于引用不可变,(也就是地址不要变,里面的内容随心所欲),而StringBuilder , StringBuffer 中都包含右append方法,可对对象中的内容进行增加。

? iii. 而String a="123"+new String("456");实际上底层是用了一个StringBuffer 进行append;

  1. a= a+1=5;(错误的赋值语句);i++是赋值语句。

  2. s.length()得到的是字符长度。

  3. 数组有length属性

  4. 数组的定义:

? i. 数组命名时名称与[]可以随意排列,但声明的二维数组中第一个中括号中必须要有值,它代表的是在该二维数组中有多少个一维数组。

? ii. float f[][] = new float[6][6];

? iii. float []f[] = new float[6][6];

? iv. float f[][] = new float[][6]; //错误

? v. float [][]f = new float[6][6];

? vi. float [][]f = new float[6][];

  1. Hashtable :继承自Dictionary类,实现了 Map 接口

? i. (1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。

? ii. (2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。

? iii. (3)HashTable直接使用对象的hashCode。

  1. HashMap:继承AbstractMap,实现Map接口【采用的链地址法解决冲突】

? i. (1)由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。

? ii. (2)不是线程安全的,HashMap可以接受为null的键(key)和值(value),最多只允许一条记录的键为Null(多条会覆盖);。

? iii. (3)HashMap重新计算hash值

  1. 集合中线程安全的类:

? i. vector,stringbuffer,hashtable,enumeration 【建议记忆法:喂!she】 Vector是实现了List接口,是一个线程安全的List。

? ii. java.util.concurrent包中的集合,例如ConcurrentHashMap,LinkedBlockingQueue 都是线程安全的

? iii. HashSet、ArrayList都可以保存null值,HashMap的Key和Value都可以是null

  1. 集合扩容

? i. 扩容, 只有超出容器容量时才会扩容,第一次创建时,仅做初始化,没有扩容动作:

? ii. ArrayList默认容量为10;扩容方案:1.5*size() + 1

? iii. HashMap(HashSet)默认容量为16;扩容方案:2 * size()

  1. java中整型默认的是int,浮点默认的是double.

? i. double类型的11.1 转成 float,是需要强制转换的

? ii. double类型的0.0 转成 int,也是需要强制转换的

? iii. int 转为封装类型Double,是无法编译的

  1. int向上自动转型:

? i. ①float x = 1;与float x = 1.0f

? ii. ②当多个精度的数字同时进行运算时,最终结果以最高精度为准。

  1. 数据类型的默认值:

? i. 字节Byte:0,b=10

? ii. 字符char:‘ \u0000′,char c=’c’

? iii. 整型(int、long、short) 0

? iv. float:0.0f,float f=0.1f

? v. double:0.0d

? vi. boolean:false

? vii. String:null【引用类型】

  1. byte类型的变量在做运算时被会转换为int类型的值

? i. byte a1=1;

? byte b1=2;

? b1+=a1;

? ii. +=会自动强转(自动装箱功能),但是+必须要手动强转

? iii. //b1=(byte) (a1+b1); //必须强转[因为a1+b1的结果是int]

  1. 数组:

? i. Number类可以被继承,Integer,Float,Double等都继承自Number类

? ii. java是面向对象的,但不是所有的都是对象,基本数据类型就不是对象,所以才会有封装类的;

  1. 数组和集合:

    i. Java集合如Map、Set、List等所有集合只能存放引用类型数据,它们都是存放引用类型数据的容器,不能存放如int、long、float、double等基础类型的数据。

? ii. 数组可以存储基础数据类型+对象

? iii. 数组长度不可变,集合可变

? iv. 数组元素个数不能获取,集合可以:size()

? v. 数组通过顺序表实现,集合通过顺序表和链表

数组 集合
长度 固定(length属性) 可变(size方法)
存储数据 基本数据类型+对象 对象
存入元素数量 无法获取 集合size()
实现方式 顺序表 顺序表、链表等

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg)

  1. list和set:

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg)

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image014.png)

  • hashset:

    • 保证元素唯?性的?式依赖于: hashCode 与equals ?法。
    • 没有索引,没有带索引的?法,也不能使?普通的for循环遍历.
    • 是?个?序的集合, 不允许存储重复的元素。
    • ?JDK1.8中,哈希表存储采?数组+链表+红?树实现,当链表?度超过阈值(8)时,将链表转换为红?树,这样??减少了查找时间,提?查询效率。
  • LinkedHashSet:

    • 底层是.个哈希表(数组+链表/红.树)+链表:多了条链表(记录元素的存储顺序),保证元素有序。
  1. 浮点型数据计算:对于有精度要求的计算,推荐使用BigDecimal, 防止精度损失导致错误。

  2. Iterator支持从源集合中安全地删除对象,只需在Iterator上调用remove()即可,it.remove();

  3. 字节流与字符流:

    i. 字节流【stream结尾】Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据。Java 中最基本的两个字节流类是InputStream和OutputStream,均为抽象类,通常使用Java类库中提供的它 们 的一系列子类。

    ii. 字符流【reader和writer结尾】Java中的字符流处理的最基本的单元是Unicode码元(大小2节), 它通常用来处理文本数据。

? iii. 字节流默认不使用缓冲区【可以使用缓冲:BufferedInputStream】;字符流使用缓冲区。

三、 关键字

? 1. final:

? i. final修饰的类为终态类,不能被继承,而抽象类是必须被继承的才有其意义的,因此,final是不能用来修饰抽象类的。

? ii. final修饰的方法为终态方法,不能被重写。而继承抽象类,必须重写其方法。

? iii. 当final关键字?修饰?个局部变量的时候,这个变量就不能进?更改

? 1. 对于基本类型来说,不可改变说的是变量当中的数据不可改变

? 2. 对于引?类型来说,不可改变说的是变量当中的地址值不可改变,但是指向的对象可以发?改变。 【比如string,可以使用反射实现】

? iv. 当final关键字?修饰?个成员变量的时候,那么这个变量也照样是不可变。

		1. 由于成员变量具有默认值,所以?了final之后必须?动赋值,不会再给默认值了。

? 2. 对于final关键字修饰的成员变量,要么使?直接赋值,要么通过构造?法赋值,?者选其?。

? 3. 必须保证类当中所有重载的构造?法,最终都会对final关键字修饰的成员变量进?赋值。

  1. 抽象方法是仅声明,并不做实现的方法。【有方法体的不能作为抽象函数】

  2. Java的关键字:

? i. true、false、null都不是关键字,而是常量。

? ii. goto、const、是保留的关键字。

  1. 关键字volatile:【不能保证线程安全】

    i. 是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而 synchronized可以修饰方法,以及代码块。

? ii. 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞

? iii. volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可 见性,因为它会将私有内存和公共内存中的数据做同步

? iv. 关键字volatile解决的是变量在多线程之间的可见性;而synchronized解决的是多线程之间资源同步问题。

? v. 依赖其他锁机制,多线程环境下的计数器可用volatile实现。

  1. this、super:

    i. 构造器中第一行默认是super(),一旦直接父类的构造器中没有无参的,那么必须显式调用父类的某个有 参构造。

? ii. 构造器中第一行的super()可以换成this(),但是this()和super()只能出现一个。

? iii. super,this关键字与super(),this()不是一回事,前者表示当前调用者的父类与其本身,后者是为了构造器相互调用。

? iv. 子类不可以继承父类的构造方法,只可以调用父类的构造方法。子类中所有的构造函数都会默认访问父类中的空参数构造函数,这是因为子类的构造函数内第一行都有默认的super()语句。

? v. super()表示子类在初始化时调用父类的空参数的构造函数来完成初始化。一个类都会有默认的空参数的构造函数,若指定了带参构造函数,那么默认的空参数的构造函数,就不存在了。这时如果子类的构造函数有默认的super()语句,那么就会出现错误,因为父类中没有空参数的构造函数。因此,在子类中默认super()语句,在父类中无对应的构造函数,必须在子类的构造函数中通过this或super(参数)指定要访问的父类中的构造函数。

四、** 循环、分支结构,程序运行结果

1. If的判断语句:

? i. Int x=0;If(x=1){},编译会报错,因为x是int型,不能将int型转化为boolean。【编译错误:“ Type mismatch: cannot convert from int to boolean ”】

? ii. 编译错误:对java源代码的语法进行检查,如果没有语法错误,就将源代码编译成字节码文件(即.class文件)。

? iii. 运行错误:对程序的逻辑错误进行检查,如果没有逻辑错误,程序的功能得到实现,输出结果。

2. switch 不能够作用在String类型上

五、 面向对象的三大特征:继承、封装、多态

1. 封装:

? i. 1、封装就是将?些细节信息隐藏起来,对于外界不可?

? ii. 2、?法就是?种封装

? iii. 3、关键字private也是?种封装

  1. 继承:

    ? i. 继承、实现的关键字:extends implements

? ii. 只有?类构造?法才能调??类构造?法。

? iii. 当?类没有?参构造?法时,使?"super(参数);"调??类重载的构造?法

? iv. super的?类构造调?,必须是?类构造?法的第?个语句。不能?个?类构造调?多次super构造。 super只能有?个,且必须是第?个。

? v. super关键字?来访问?类内容?法有三种:

? 1. 在?类的成员?法中,访问?类的成员变量。

? 2. 在?类的成员?法中,访问?类的成员?法。

? 3. 在?类的构造?法中,访问?类的构造?法。

? vi. this关键字?来访问本类内容?法有三种:

? 1. 在本类的成员?法中,访问本类的成员变量。

? 2. 在本类的成员?法中,访问本类的另?个成员?法。

? 3. 在本类的构造?法中,访问本类的另?个构造?法。

? 4. 注意:

? a) 若构造?法中含有this(...)调?,则必须是第?个语句。

? b) super和this两种构造调?,不能在同?个构造?法中同时使?。

? vii. 抽象类:

? 1. 抽象类的?类,必须重写抽象类中所有的抽象?法,否则,编译?法通过。除?该?类也是抽象类。

? 2. 抽象方法只可以被public 和 protected修饰;

  1. 多态:

? i. 继承(extends)和实现(implements)是多态的前提。

? ii. 多态:

? 1. 代码当中体现多态性,其实就是?句话:?类引?指向?类对象。

? 2. 格式:

? a) ?类对象 对象名 = new ?类名称(); (把?类当作?类使?)

? b) 或者接?名称 对象名 = new 实现类名称();

? 3. 在多态的代码当中,成员变量的访问规则有两种:

? a) 直接通过对象名称访问成员变量:看等号左边是谁,优先?谁,没有则向上找

? b)间接通过成员?法访问成员变量:看该?法属于谁,优先?谁,没有则向上找

? 4.在多态的代码当中,成员?法的访问规则是:

? a)看new的是谁,就优先?谁,没有则向上找。

? iii. 向下转型需要强制:Cat cat = (Cat) animal;【前提是:Animal animal=new cat()】

? 1. Animal animal=new Animal(); cat cat=(cat)animal3;这种转型就是错的,因为animal本来是Animal 的对象,不能还原到cat类型。

? iv. 接口:

? 1. 接口中包含的内容:

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image016.png)

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image018.jpg)

? 2. 接?当中可以定义"成员变量":

? a) 但是必须使?public static final三个关键字进?修饰。(其实就是常量)

? b)接?当中的常量,可以省略public static final。

? c)当中的常量必须进?赋值,不能不赋值。

? 3. 接?当中的抽象?法修饰符:

? a) 修饰符必须是两个固定的关键字:public abstract

? b)这两个关键字修饰符,可以选择性地省略。

? 4. 接口中的默认方法:(java8+)

? a) 定义:public default 返回值类型 ?法名称(参数列表) {

? //?法体

? }

? b)接?当中的默认?法,可以解决接?升级的问题,默认?法会被接?的实现类继承。

? i. 接?的默认?法,可以通过接?实现类对象直接调?,也可以被接?实现类进?覆盖重写。

? 5. 接口中的静态方法(Java 8+):

? a)定义:

? i. public static 返回值类型方法名.(参数列表) {

? //.方法体

? }

? b)调用:

? i. 不能通过接口实现类的对象来调用接口当中的静态方法**。一个类可以实现多个接口,多个接口中 的静态方法有可能会产生冲突。

? c)正确使用方法:通过接口名称直接调用其中的静态方法。

? i. 格式:接口名称.静态方法名(参数);

? 6. 接口中的私有方法:(Java 9+

? a)需要抽取?个公共?法,?来解决两个及两个以上默认?法之间代码重复的问题。这个共有?法不应 该让实现类使?,应该是私有化的。

? 7. 接?的实现类必须覆盖重写接?中所有的抽象?法,如果实现类并没有覆盖重写接?中所有的抽象? 法,那么这个实现类必须是抽象类。

? 8. 接?是没有静态代码块或者构造?法的。

? 9. 继承的优先级?于接?【如果?个接?的实现类所继承的直接?类当中的?法,和接?中定义的默认? 法产?了冲突,此时优先??类当中的?法。】

  1. 外部类的修饰符只能是public 和default【默认不写】

  2. 内部类:

    i. 成员内部类:(修饰符:四种都可以)【可以是静态static的,也可用public,default,protected和private修饰(因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能)】

    ? 1. 内部类使?外部类,可以随意访问;外部类使?内部类,需要借助于内部类对象。

    ? 2. 间接?式:在外部类的?法当中使?内部类;然后main只是调?外部类的?法。

    ? 3. 直接?式,格式: 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类

    ? 4. 名称();

? ii. 局部内部类:(不能写任何修饰符)但可以是abstract和final,也不能使用static

? 1. 概念:定义在?个"?法"内部的类就是?个局部内部类。

? 2. "局部":只有当前所属的?法才能使?它,在这个?法外部不能使?。

? iii. 匿名内部类(属于局部内部类):

? 1. 匿名内部类在创建对象的时候,只能使?唯?的?次,如果希望多次创建对象,?且类的内容?样的 话,就必须使?单独定义的实现类。

? 2. 匿名对象,在调??法的时候只能调?唯?的?次,如果希望同?个对象,调?多次?法,那么必须给 对象起个名字。

? 3. 匿名内部类是省略了实现类/?类的名称,匿名对象是省略了对象名称,?者不是?回事。

? 4. 匿名内部类不可以定义构造器(没有名字)

? 5. 匿名内部类中不能含有静态成员变量和静态方法

? 6.使用匿名内部类时,必须继承一个类或实现一个接口【但是两者不可兼得,同时也只能继承一个类或者实 现一个接口。】

? 7. 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

  1. c是面向过程,c++面向对象,JAVA面向对象,汇编是面向机器

  2. 将一个类设计为单例模式,必须私有其空参数构造方法,并且还不能定义有参数的构造方法。

  3. 方法的重载与重写:

    • i. 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表,【与返回值类型无关;与访问修饰符无关】。最常用的地方就是构造器的重载。
    • ii. 重写(override)是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。【如果子类中方法和父类的方法名,参数,访问权限,异常都相同,只有返回值类型不同会编译不通过。不是重写】
    • iii. 重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。在面向对象原则里,重写意味着可以重写任何现有方法。
    • iv. 方法重写应遵循“三同一小一大”原则:
    • “三同”:即方法名相同,形参列表相同,返回值类型相同;
    • “一小”:子类方法声明抛出的异常比父类方法声明抛出的异常更小或者相等;
    • “一大”:子类方法的访问修饰符应比父类方法更大或相等。
  4. 重写:

? i. 只要是被子类重写的方法,不被super调用,都是调用子类方法。

? ii. 向上转型:父类只能调用父类方法或者子类覆写后的方法,而子类中的单独方法则是无法调用的。

  1. 构造方法的调用方式:

? i. 调用本类的构造函数:this(a,b,c),new student(a,b,c)两种方法都可以。

? ii. 构造方法可以用public,protected,default,private

  1. 继承:【子类将继承父类的所有的数据域和方法】
    * i. 在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象。
    * ii. 所谓的继承使子类拥有父类所有的属性和方法其实可以这样理解,子类对象确实拥有父类对象中所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。

  2. 抽象类和接口:
    * i. 抽象类可以有构造方法【不过不是用来实例化对象的,是用来初始化的】,接口没有构造方法
    * ii. 抽象类可以有普通成员变量,接口没有普通成员变量
    * iii. 抽象类和接口都可有静态成员变量,抽象类中静态成员变量访问类型任意,接口只能public static final(默认)
    * iv. 抽象类可以没有抽象方法,抽象类可以有普通方法,接口中都是抽象方法
    * v. 抽象类可以有静态方法,接口不能有静态方法【静态方法在子类中不能被重写,接口需要被实现,矛盾,故:抽象方法不能是静态的】。
    * vi. 抽象类中的方法可以是public、protected;接口方法默认当然是public abstract
    * vii. abstract类中可以有private的成员。
    * viii. abstract不能与final并列修饰同一个类

  3. 下面哪些情况下需要使用抽象类?

    • 当一个类的一个或多个方法是抽象方法时
    • 当类是一个抽象类的子类,并且不能为任何抽象方法提供任何实现细节或方法体时
    • 当一个类实现一个接口,并且不能为任何抽象方法提供实现细节或方法体时
  4. Java的5种创建对象的方式:

    • 使用 new 关键字(最常用): ObjectName obj = new ObjectName();
    • 使用反射的Class类的newInstance()方法: ObjectName obj = ObjectName.class.newInstance();
    • 使用反射的Constructor类的newInstance()方法: ObjectName obj = ObjectName.class.getConstructor.newInstance();
    • 使用对象克隆clone()方法: ObjectName obj = obj.clone();
    • 使用反序列化(ObjectInputStream)的readObject()方法: try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) { ObjectName obj = ois.readObject(); }
  5. 类的加载顺序:【基类构造函数>派生类对象成员构造函数>派生类本身的构造函数】

    • i. 父类静态域——》子类静态域——》父类成员初始化——》父类构造块——》1父类构造方法——》2子类成员初始化——》子类构造块——》3子类构造方法;
    • ii. (1) 父类静态对象和静态代码块
    • iii. (2) 子类静态对象和静态代码块
    • iv. (3) 父类非静态对象和非静态代码块
    • v. (4) 父类构造函数
    • vi. (5) 子类 非静态对象和非静态代码块
    • vii. (6) 子类构造函数
    • viii. 静态块:用static申明,JVM加载类时执行,仅执行一次
    • ix. 构造块:类中直接用{}定义,每一次创建对象时执行
    • x. 执行顺序优先级:静态块>main()>构造块>构造方法
  6. JDK8开始,接口中可以定义有方法体的方法,方法必须被default和static修饰。除此之外,其他方法都是抽象方法。

  7. 不会初始化子类的几种

? i. 1. 调用的是父类的static方法或者字段【S.abc】

? ii. 2.调用的是父类的final方法或者字段【int x = ConstClass.value; 】

? iii. 3. 通过数组来引用【SuperClass[] sca = new SuperClass[10]】

  1. 静态方法:【静态方法不可以使用非静态变量】
    * i. 静态方法是不用创建对象就直接调用,所以在静态方法中没有this指针,不能访问所属类的非静态变量和方法,只能访问方法体内的局部变量、自己的参数和静态变量,而非静态变量是给一个类的实例化对象调用的,一个是类调用,一个是类对象调用。
    * ii. 在非静态内部类中不可以声明静态成员
    * iii. 静态方法中,可以调用其他类的静态方法
    * iv. 静态方法中可以调用实例方法,但是必须要new一个对象
    * v. 静态方法中不能用this.实例方法,因为此时对象还没有(this代表当前对象)
    * vi. 静态方法不占用对象的内存空间,而非静态方法占用对象的内存空间
    * vii. 类方法可以使用类名调用,也可以通过对象调用。
    * viii. 实例方法可以访问类变量
    * ix. 在类方法中调用本类的类方法时可直接调用

19.静态成员变量调用

? i. 如果是本类使用,可以直接就用静态变量名。

? ii. 如果是其他类使用,可以使用类名来调用,也可以创建一个实例对象来调用。

? iii. 如果静态变量所在的类是静态类,那么不管在本类里或者在其他外部类,都可以直接使用静态变量名。

  1. 方法内定义的变量没有初始值,必须要进行初始化。类中定义的变量可以不需要赋予初始值,默认初始值为0。

  2. null:

? i. 1、alert(null instanceof Object); 返回值为false。

? ii. 2、typeof(null) == 'object'

? iii. 解释:null表示为空的引用;undefined和null比较特殊,虽然null的类型是object,但是null不具有任何 对象的特性

**22. **instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例。

  1. 局部变量

? i. 不可以使用 private,protected,public 修饰 局部变量。final 可以修饰局部变量,但这样修饰后它会变为常量。

? ii. 在方法中定义的局部变量在该方法加载【而非被执行】时创建;局部变量在使用前必须被初始化。

**24. 参数传递:

? i. 值传递:Java中原始数据类型都是值传递,传递的是值得副本,形参的改变不会影响实际参数的值

? ii. 引用传递传递的是引用类型数据,包括String,数组,列表, map,类对象等类型,形参与实参指向的是同一内存地址,因此形参改变会影响实参的值。【?】

**25. Java****方法中的参数传递:

? i. A、在方法中,修改一个基础类型的参数永远不会影响原始参数值。

? ii. B、在方法中,改变一个对象参数的引用永远不会影响到原始引用。然而,它会在堆中创建了一个全新的对象。(译者注:指的是包装类和immutable对象)

? iii. C、在方法中,修改一个对象的属性会影响原始对象参数。

? iv. D、在方法中,修改集合和Map会影响原始集合参数。

? v.

  1. instanceof运算符能够用来判断一个对象是否为:

? i. 一个类的实例

? ii. 一个实现指定接口的类的实例

? iii. 一个子类的实例

六、异常

1. 所有异常的父类都是Throwable。java异常分为Error(虚拟机异常)和Exception(编码异常)
 * i.     Error:(非检查异常) Java虚拟机无法解决的严重问题,代表了JVM本身的错误。错误不能被程序员通过	代码处理,Error很少出现.比如:StackOverflowError(堆栈溢出)和OutOfMemoryError(内存不足)。一般	不编写针对性的代码进行处理。
 *  ii.     Excepion: 因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理(是程序本	身可以处理的异常。)。例如: 空指针访问,文件不存在,网络连接中断,数组角标越界。异常处理: try{....}catch(Exception e){...}finally{...}
 * iii.     运行时异常RuntimeException(非检查异常),是Exception中比较特别的,是Excepion的子类。通常RuntimeException不需要在方法签名中声明,默认抛出到父类。
  1. 非运行时异常(检查异常):编译器要求必须处置的异常,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

  2. 非检查异常:这样的异常发?的原因多半是代码写的有问题。javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。

  3. 检查异常:这样的异常?般是由程序的运?环境导致的。如SQLException , IOException,ClassNotFoundException等。

  4. 异常三种方式:

? i. 用try-catch 捕获异常;

? ii. 用try-finally 清除异常;

? iii. 用try-catch-finally 处理所有的异常. 三者选一种即可

? iv. 注:finally语句先于 return 和 throw语句执行

  1. throws与throw

    • i. throws【方法可能抛出异常的声明】出现在方法函数头;而throw出现在函数体。
    • ii. throws【语句抛出一个异常】表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象,throw语句必须写在函数中。
  2. finally一定会在return之前执行,但是如果finally使用了return或者throw语句,将会使try catch中的return或者throw失效。

  3. catch只会匹配一个,因为只要匹配了一个,虚拟机就会使整个语句退出。一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或 其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块

  4. 常见的运行时异常包括 空指针异常 类型转换异常 数组越界异常 数组存储异常 缓冲区溢出异常 算术异常等

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image020.png)

  1. 由于异常处理系统就近寻找匹配异常处理程序,应先子类后父类【范围越大越放后面】

  2. try{}catch(){}中有throw:

? i. 1.若catch(){}块中,如果有throw 语句,则,try{}catch(){} finally{}块之外的代码不执行;否则,执行。

? ii. 2.try{}中有异常,则异常下面代码不执行。

? iii. 3.finally{}中代码必执行。

  1. 如果某异常继承RuntimeException,则该异常可以不被声明。

  2. JAVA 异常类的描述,说法正确的有():ABC
    * i. A、异常的继承结构:基类为 Throwable,Error 和 Exception 。实现 Throwable, RuntimeException 和 IOException 等继承 Exception
    * ii. B、非 RuntimeException 一般是外部错误(不考虑Error的情况下),其可以在当前类被 try{}catch 语句块所捕获
    * iii. C、Error 类体系描述了 Java 运行系统中的内部错误以及资源耗尽的情形,Error 不需要捕捉

  3. ?个try?少要有?个catch块,否则,?少要有1个finally块。但是finally不是?来处理异常的,finally不会捕获异常。

  4. 每?个catch块?于处理?个异常。异常匹配是按照catch块的顺序从上往下寻找的,只有第?个匹配的catch会得到执?。匹配时,不仅运?精确匹配,也?持?类匹配,因此,如果同?个try块下的多个catch异常类型有??关系,应该将?类异常放在前?,?类异常放在后?,这样保证每个catch块都有存在的意义。

  5. 自定义异常:
    * i. 如果要?定义异常类,则扩展Exception类即可,因此这样的?定义异常都属于检查异常(checked exception)。如果要?定义?检查异常,则扩展?RuntimeException。

七、基础框架知识

1. Spring
 * i. 本身并不直接管理事务,而是提供了事务管理器接口,对于不同的框架或者数据源则用不同的事务管理器。
 *  ii. Spring提供了AOP方式的日志系统
 *  iii. Spring并没有为我们提供日志系统,我们需要使用AOP(面向方面编程)的方式,借助Spring与日志系统log4j实现我们自己的日志系统。
  1. 关于struts项目中的类与MVC模式的对应关系:

? i. Jsp文件实现视图View的功能

? ii. ActionServlet这一个类是整个struts项目的控制器

  1. Spring是一系列轻量级Java EE框架的集合

? i. Spring中包含一个“依赖注入”模式的实现

? ii. 使用Spring可以实现声明式事务

? iii. Spring并没有为我们提供日志系统,我们需要使用AOP(面向方面编程)的方式,借助Spring与日志系 统log4j实现我们自己的日志系统。

  1. Mybatis映射配置文件标签有:Datasource

  2. Spring MVC的核心控制器DispatcherServlet的作用:

? i. 初始化上下文应用对象ApplicationContext

? ii. 负责接收HTTP请求

? iii. 加载配置文件

  1. 顶层容器是指可以不能被其他容器包含,是容纳其他容器的容器组件,
    顶层容器包含JApplet、JDialog、JFrame和JWindow及其子类.

  2. 获取值:

? i. getParameter()是获取POST/GET传递的参数值;

? ii. getInitParameter获取Tomcat的server.xml中设置Context的初始化参数

? iii. getAttribute()是获取对象容器中的数据值;

? iv. getRequestDispatcher是请求转发。

  1. doGet/doPost 则是在 javax.servlet.http.HttpServlet 中实现的

八、虚拟机基础知识

1. 堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
  1. jre判断程序是否执行结束的标准是:所有的前台线程执行完毕。

  2. off-heap:JVM进程管理的内存

  3. full GC触发的条件可能有:

? i. 老年代满

? ii. 持久代满

? iii. System.gc()

  1. 属于JVM规范内存区域有:程序计数器、虚拟机栈、本地方法栈、堆、方法区(包括常量池)。

九、Java堆、栈

1. 变量:

? i. 在函数中定义的变量不能与其所在函数的形参同名

? ii. 在函数中定义的变量,其存储单元在内存的栈区

? iii. 根据作用域规则,在函数中定义的变量只能在函数中引用

  1. 首先说明栈内存和堆内存里存放的是什么

? i. 栈内存中存放函数中定义的一些基本类型的变量和对象的引用变量

? ii. 堆内存中存放new创建的对象和数组

? iii. 简单的来说,堆主要是用来存放对象的,栈主要是用来执行程序的。这么做是因为:

? 1. 栈的存取速度快,栈数据可以共享,但是栈中的数据大小和生存期必须确定,缺乏灵活性中存放一些基 本类型的对象和对象句柄

? 2. 堆是操作系统分配给自己内存,由于从操作系统管理的内存分配,所以再分配和销毁时都需要占用时 间,因此用堆的效率非常低,但是优点在于编译器不需要指导从堆里分配多少存储控件,也不需要知道存储 的数据要再堆里停留多长事件,因此用堆保存数据时会得到更大的灵活性

十、Java多线程

1. 进程:是操作系统内在内存中独立运行的程序,有自己的地址空间
2. 线程:是进程内部单一的一个顺序控制流。

? i. 每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。

? ii. 线程: 轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程 切换的开销小。

? iii. 多线程: 在同一个进程中有多个顺序流同时执行

  1. 多线程的实现方法:

? i. 继承Thread类,实现Runable接口,但都要实现run方法。

? ii. sleep来自Thread,wait来自Object。

? iii. 当调用start(),notify(),notifyAll(), 或sleep、wait时间到了,程序不会立即进入执行状态,线程会进入可 运行状态,并在资源空闲时开始执行。

  1. 为了从一个Runnable对象产生线程,必须再单独创建一个线程对象,并把Runnable对象传递给它。

  2. 使用Runnable接口

? i. 可以将代码和数据分开,形成清晰的模型;

? ii. 还可以从其他类继承;

? iii. 保持程序风格的一致性。

  1. 直接继承Thread类

? i. 不能再从其他类继承;

? ii. 编写简单,可以直接操纵线程,无需使用 Thread. currentThread()。

  1. 线程的状态:

![img](file:///C:/Users/梦想天~1/AppData/Local/Temp/msohtmlclip1/01/clip_image022.png)

? i. 新建状态(New):

? 用new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在区中被分配了内存。

? ii. 就绪状态(Runnable):

? 当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态,Java虚拟机会为它创建方法 调 用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权。

? iii. 运行状态(Running):

? 处于这个状态的线程占用CPU,执行程序代码。只有处于就绪状态的线程才有机会转到运行状态。

? iv. 阻塞状态(Blocked):

? 阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分 配CPU。直到线程重新进入就绪状态,它才有机会转到运行状态。

? v. 阻塞状态可分为以下3种:

? 1. 位于对象等待池中的阻塞状态(Blocked in object’s wait pool):当线程处于运行状态时,如果执行了 某个对象的wait()方法,Java虚拟机就会把线程放到这个对象的等待池中,这涉及到“线程通信”的内容。

? 2. 位于对象锁池中的阻塞状态(Blocked in object’s lock pool):当线程处于运行状态时,试图获得某个 对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池 中,这涉及到“线程同步”的内容。

? 3. 其他阻塞状态(Otherwise Blocked):当前线程执行了sleep()方法,或者调用了其他线程的join()方 法,或者发出了I/O请求时,就会进入这个状态。

? vi. 死亡状态(Dead):

? 当线程退出run()方法时,就进入死亡状态,该线程结束生命周期。

  1. Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

  2. 为了确保在任何时刻一个共享对象只被一个线程使用,必须使用“同步(synchronized)”

  3. 有两种方式实现同步:

? i. 使用同步方法

? 1. synchronized void methodA() { }

? ii. 使用同步块

? 1. synchronized(obj //obj是被锁定的对象){ //要同步的语句}

  1. 线程间的通信方式有三种:完全共享数据,通过监视器,通过join。

  2. 线程池的作用:

    • i. 减少资源的开销
      减少了每次创建线程、销毁线程的开销。
    • ii. 提高响应速度,每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度。
    • iii. 提高线程的可管理性 ,线程是一种稀缺资源,若不加以限制,不仅会占用大量资源,而且会影响系统的稳定性。
  3. 锁的对象:

? i. 修饰非静态方法 锁的是this 对象

? ii. 修饰静态方法 锁的是class对象

  1. 死锁:产生死锁的四个必要条件:

? i. 互斥条件:一个资源每次只能被一个进程使用。

? ii. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

? iii. 不可剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

? iv. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

  1. sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。

  2. wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

  3. 让线程停止执行的方法有:

? i. sleep:导致此线程暂停执行指定时间

? ii. stop:这个方法将终止所有未结束的方法,包括run方法。

? iii. synchronized():对象锁

? iv. yield:当前正在被服务的线程可能觉得cpu的服务质量不够好,于是提前退出,这就是yield。

? v. wait:当前正在被服务的线程需要睡一会,醒来后继续被服务

  1. 常用方法:

? i. public void start();//启动该线程,将导致run方法被自动调用。该方法将立即返回,新线程将运行

? ii. public void run();//必须覆盖该方法,在方法体中添加你想要在该线程中执行的代码

? iii. public static void sleep(long millis) throws InterruptedException;//使当前正在执行的线程睡眠指定 的时间

? iv. public void interrupt();//用于将一个中断请求发送给线程

? v. public static boolean interrupted();//用于测试当前线程(即正在执行该指令的线程)是否已经被中断

? vi. public boolean isInterrupted();//用于测试某个线程是否已经被中断

? vii. public final boolean isAlive();//用于测试某个线程是否还活着

? viii. public final void setPriority(int newPriority);//设置线程的优先级

? ix. public final void join(long millis) throws InterruptedException;//使某个线程等待指定的时间。调用 某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。

? x. public final int getPriority() ; //获得线程的优先级

? xi. public static Thread currentThread();返回代表当前正在执行的线程的Thread对象

? xii. public static void yield() ;使当前正在执行的线程临时暂停,以使其它的线程运行

? xiii. public final void wait(long timeout) throws InterruptedException;当前线程被中断,并进入到一个 对象的等待列表中,直到另外的线程调用同一个对象上的notify() 或notifyAll() 方法

? xiv. public final void notify() ;用于将对象等待列表中的任选的一个线程唤醒,使它再次成为可运行的线程

? xv. public final void notifyAll();用于将对象等待列表中的所有线程唤醒,使它们再次成为可运行的线程

  1. 线程的互斥锁机制:synchronized,lock,condition

  2. 线程调度算法是平台独立的【线程调度分为协同式调度和抢占式调度,Java使用的是抢占式调度,也就是每个线程将由操作系统来分配执行时间,线程的切换不由线程本身来决定(协同式调度)】

  3. Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。

**22. start****是开启线程,run是线程的执行体,run是线程执行的入口。

**23. **CyclicBarrier和CountDownLatch都可以让一组线程等待其他线程。前者是让一组线程相互等待到某 一 个状态再执行。后者是一个线程等待其他线程结束再执行。

  1. Callable****中的call比Runnable中的run厉害就厉害在有返回值和可以抛出异常。同时这个返回值和线程池一起用的时候可以返回一个异步对象Future。

**25. start****是把线程从new变成了runnable

  1. 常用的方法:start()、run()、sleep()、stop()

? i. suspend()方法:使线程挂起。

? ii. resume()方法:恢复挂起的线程。

? iii. yield()方法:把线程移到队列的尾部。

? iv. stop()方法:结束线程生命周期并执行清理工作。

? v. destroy()方法:结束线程生命周期但不做清理工作。

**27. 通过线程对象的setPriority()方法设置优先级

? i. 缺省优先级为5

? ii. 三个常数:MAX_PRIORITY、MIN_PRIORITY、NORM_PRIORITY

十一、 文件读写

1.  OutputStream用于写操作、InputStream用于读操作。
2.  File:

? i. File类能够存储文件属性

? ii. File类能够读写文件 【错误。能够读写文件的是数据流(OutputStream和InputStream)】

? iii. File类能够建立文件

? iv. File类能够获取文件目录信息