子父类加载的规则
简单来说: 父类静态内容 ——> 子类静态内容 ——> 父类构造代码块 ——> 父类构造方法 ——> 子类构造代码块 ——> 子类构造方法
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则: 被重载的方法必须改变参数列表(参数个数或类型不一样); 被重载的方法可以改变返回类型; 被重载的方法可以改变访问修饰符; 被重载的方法可以声明新的或更广的检查异常; 方法能够在同一个类中或者在一个子类中被重载。 无法以返回值类型作为重载函数的区分标准。
this表示当前对象: this.属性 区别成员变量和局部变量 this.() 调用本类的某个方法 this() 表示调用本类构造方法,只能用在构造方法的第一行语句。 this关键字只能出现在非static修饰的代码中
super表示父类对象: super.属性 表示父类对象中的成员变量 super.方法()表示父类对象中定义的方法 super() 表示调用父类构造方法 可以指定参数,比如super("Tom",23); 任何一个构造方法的第一行默认是super(); 可以写上,如果未写,会隐式调用super(); super()只能在构造方法的第一行使用。 this()和super()都只能在构造的第一行出现,所以只能选择其一。 写了this()就不会隐式调用super()。
类创建的过程
任何类在创建之初,都有一个默认的无参构造方法,它是 super() 的一条默认通路。构造方法的参数列表决定了调用通路的选择;如果子类指定调用父类的某个构造方法,super 就会不断的向上溯源(每个对象必然是继承一个父类,这块地意思就是沿着一层一层的路径找到 Object 类);如果没有指定,则调用 super() 。如果父类没有提供默认的构造方法,子类在继承时就会编译错误。
lass Father{ public Father(int a){ } }
//这块就会报错,因为子类没有明确的指定继承父类的某个构造方法,而且父类也没有默认的无参构造方法
class Son1 extends Father{
}
//正确的方式
class Son2 extends Father{
public Son2{
super(1);
}
}
如果父类坚持不提供无参的构造方法,就必须如上代码的Son2类的无参构造方法中使用 super 方式调用父类的某个有参构造方法。
3、引用构造函数
super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
2.3 this 和 super 使用注意
(1) 如果 this 和 super 指代构造方法,则必须位于方法体的第一行。换句话说,在一个构造方法中,this 和 super 只能出现一个,且只能出现一次,否则在实例化对象时,会因为子类调用多个构造方法而造成混乱。
(2) 由于 this 和 super 都在实例化阶段调用,所以不能在静态方法和静态代码块中使用 this 和 super 关键字。
(3) this 还可以值代当前对象,比如在同步代码块 synchronized(this){....}中,super 就不具备这种能力。但是 super 也有自己独特的功能,在子类覆盖父类方法的时候,可以使用 super 调用父类的同名方法。
接口:
A) 接口没有提供构造方法
B) 接口中的方法默认使用public、abstract修饰
C) 接口中的属性默认使用public、static、final修饰
抽象类和接口的区别:
抽象类不能被实例化只能被继承;
抽象类不能被实例化只能被继承;
抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;
一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类
抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。
接口
接口可以包含变量、方法;变量被隐式指定为public static final,方法被隐式指定为public abstract(JDK1.8之前)
接口支持多继承,即一个接口可以extends多个接口,间接的解决了Java中类的单继承问题;
一个类可以实现多个接口;
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
方法的重载和重写:
构造方法可以重载,不能重写
方法的重载和访问修饰符以及返回值类型无关
参数的个数相同参数的类型种类也相同,但是由于参数的顺序的不同也 构成重载。
Error异常和Exception异常都继承于throwable异常类。
Exception包括RuntimeException和RuntimeException之外的异常
try-catch-finally语句块中 try可以单独与finally一起使用
自定义异常必须继承Exception或者RuntimeException,不能继承error
自定义异常可以更加明确定位异常出错的位置和给出详细出错信息
HashMap能够将键设为null,也可以将值设为null。
C) 使用ObjectOutputStream类完成对象存储,使用ObjectInputStream类完成对象读取
D) 对象序列化的所属类需要实现Serializable接口
jdbc
PreparedStatement是CallableStatement的父接口
获取ResutlSet对象rst的第一行数据 rst.next();
Statement sta=con.createStatement(); ResultSet rst=sta.executeQuery(“select * from book”);
PreparedStatement pst=con.preparedStatement(“select * from book”); ResultSet rst=pst.executeQuery();
建立与数据库连接 DriverManager
使用JDBC连接数据库
导入驱动包、加载驱动、建立于数据库的连接、发送并处理SQL语句、 关闭连接
父类的构造方法是否可以被子类覆盖(重写)?
答:父类的构造方法不可以被子类覆盖,因为父类和子类的类名是不可能一样的。
面向对象的特征有哪些方面:
抽象:继承:封装:多态性:
Collection是集合类的上级接口
Collections是针对集合类的一个帮助类
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法
sleep是线程类(Thread)的方法,调用sleep不会释放对象锁。
wait是Object类的方法
volatile关键字用在多线程同步中,可保证读取的可见性,JVM只是保证从主内存加载到线程工作内存的值是最新的读取值,而非cache中。但多个线程对volatile的写操作,无法保证线程安全。
这些类都是Reader和Writer的子类 面向字符的操作
InputStream和OutputStream的子类 面向字节的操作
序列化调用对象,是将存在磁盘的对象文件加载到内存中
用final修饰的类是不允许被继承的
abstract类中的非abstract方法是可以用final修饰的
不允许使用static修饰abstract方法
内部类的类名只能在定义它的类或程序段中或在表达式内部匿名使用
内部类可以使用它所在类的静态成员变量和实例成员变量
内部类可作为其他类的成员,而且可访问它所在类的成员
FileInputStream 读字符文件
装箱拆箱
总结:区分成员变量和局部变量,局部变量
this.方法名称 用来访问本类的成员方法
this(); 访问本类的构造方法 ()中可以有参数的 如果有参数 就是调用指定的有参构造
1.this() 不能使用在普通方法中 只能写在构造方法中
2.必须是构造方法中的第一条语句
this.属性名称 指的是访问类中的成员变量,用来区分成员变量和局部变量(重名问题)
String、stiringbuffer和stringbiuder的区别 String 字符串常量、不可变 字符串拼接时,是不同的两个空间 Stringbuffer 字符串变量 可变 线程安全,字符串拼接时,直接在后面追加 stringbiuder 字符串变量 可变 非线程安全,字符串拼接时,直接在后面追加 1.StringBuilder执行效率高于StringBuffer高于String. 2.String是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象, StringBuffer和StringBuilder都是可变的,当进行字符串拼接时采用append方 法,在原来的基础上进行追加,所以性能比String要高,又因为StringBuffer 是 线程安全的而StringBuilder是线程非安全的,所以StringBuilder的效率高于 StringBuffer. 3.对于大数据量的字符串的拼接,采用StringBuffer,StringBuilder.
五、Hashtable与HashMap的区别 HashMap不是线程安全的,HashTable是线程安全。 HashMap允许空(null)的键和值(key),HashTable则不允许。 HashMap性能优于Hashtable。
六、九大隐式对象 输入/输出对象: request response out 作用域通信对象: session application pageContext Servlet 对象: page config 错误对象: exception
十五、java的基本数据类型 数据类型 大小 boolean(布尔型) 1位 byte(字节) 1(8位) char(字符型) 2(16位) shot(短整型) 2(16位) int(整型) 4(32位) float(浮点型) 4(32位) long(长整型) 8(32位) double(双精度) 8(64位) 冒泡排序:从最后一位选最小值,判断位判断完一轮,sort[j]往后移动 for (int i = 0; i < sort.length - 1; i++) { for (int j = 0; j < sort.length - i - 1; j++) { if (sort[j] < sort[j + 1]) { temp = sort[j]; sort[j] = sort[j + 1]; sort[j + 1] = temp; } } } 递归实现阶乘 public class Multiply { public static int multiply(int num) { if (num < 0) { System.out.println("请输入大于0的数!"); return -1; } else if (num == 0 || num == 1) { return 1; } else { return multiply(num - 1) * num; } } public static void main(String[] args) { System.out.println(multiply(10)); } }
饿汉式:
public class Singleton1 {
private Singleton1() {};
private static Singleton1 single = new Singleton1();
public static Singleton1 getInstance() {
return single;
}
}
懒汉式:
public class Singleton2 {
private Singleton2() {}
private static Singleton2 single=null;
public static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
线程安全:
public class Singleton3 {
private Singleton3() {}
private static Singleton3 single ;
public static Singleton3 getInstance() {
if(null == single){
synchronized(single ){
if(null == single){
single = new Singleton3();
}
}
}
return single;
}
}
java 异常是程序运行过程中出现的错误。Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。在Java API中定义了许多异常类,分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常(非runtimeException),也称之为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
运行时异常: 都是RuntimeException类及其子类异常: IndexOutOfBoundsException 索引越界异常 ArithmeticException:数学计算异常 NullPointerException:空指针异常 ArrayOutOfBoundsException:数组索引越界异常 ClassNotFoundException:类文件未找到异常 ClassCastException:造型异常(类型转换异常) 这些异常是不检查异常(Unchecked Exception),程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的。
非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如: IOException、文件读写异常 FileNotFoundException:文件未找到异常 EOFException:读写文件尾异常 MalformedURLException:URL格式错误异常 SocketException:Socket异常 SQLException:SQL数据库异常
字节流与字符流的区别:
在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。
只是读写文件,和文件内容无关的,一般选择字节流。
final,finally,finalize 三者区别 当final修饰一个变量的时候,变量变成一个常量,它不能被二次赋值 当final修饰的变量为静态变量(即由static修饰)时,必须在声明这个变 量的时候给它赋值 当final修饰方法时,该方法不能被重写 当final修饰类时,该类不能被继承 Final不能修饰抽象类,因为抽象类中会有需要子类实现的抽 Final不能修饰接口,因为接口中有需要其实现类来实现的方法 Finally只能与try/catch语句结合使用,finally语句块中的语句一定会执行, 并且会在return,continue,break关键字之前执行
finalize: Finalize是一个方法,属于java.lang.Object类,finalize()方法是GC (garbage collector垃圾回收)运行机制的一部分,finalize()方法是在 GC清理它所从 属的对象时被调用的
Jdk【Java Development ToolKit】就是java开发工具箱, JDK是整个JAVA的核心里边包含了jre,它除了包含jre之外还包含了一些javac的工具类,把java源文件编译成class文件,java文件是用来运行这个程序的,除此之外,里边还包含了java源生的API,java.lang.integer在rt的jar包里边【可以在项目中看到】,通过rt这个jar包来调用我们的这些io流写入写出等
Jre【Java Runtime Enviromental】是java运行时环境,那么所谓的java运行时环境,就是为了保证java程序能够运行时,所必备的一基础环境,也就是它只是保证java程序运行的,不能用来开发,而jdk才是用来开发的,所有的Java程序都要在JRE下才能运行。
Jre里边包含jvm Jvm:【Java Virtual Mechinal】因为jre是java运行时环境,java运行靠什么运行,而底层就是依赖于jvm,即java虚拟机,java虚拟机用来加载类文件,java中之所以有跨平台的作用,就是因为我们的jvm
J2se是基于jdk和jre, JDK是整个JAVA的核心里边包含了jre, Jre里边包含jvm
2.有抽象方法的类一定是抽象类,但是抽象类里面不一定有抽象方法; 接口里面所有的方法的默认修饰符为public abstract,接口里的成员变 量默认的修饰符为 pulbic static final。
关系
接口和接口 继承 接口和抽象类 抽象类实现接口 接口和类 类实现接口 类和抽象类 类继承抽象类 类和类 继承
3.实现线程的两种方式:继承Thread类,实现Runable接口
内存泄露:申请的内存一直无法释放
内存溢出(out of memory)是指应用程序在申请内存时, 没有足够的内存空间供其使用。
java异常
what:异常类型回答了什么被抛出
where:异常堆栈跟踪回答了在哪抛出
why:异常信息回答了为什么被抛出
最后
出现异常的时候,先查找捕获的类型是否包含这个异常,如果包含,则执行里面的代码块,有fially方法,则执行,再返回。捕获到异常,一点要打印异常信息,否则在线上,很难发现报错是哪里的问题
只要发现,就及时抛出到上一层,在可以处理该异常的类中,再去哺抓
因为以下两个原因,再开发中,不要包不出现异常的代码,同时不要通过异常去控制流程,而是使用if else
有的类定义时可以不定义构造函数,所以构造函数不是必需
的 错:不定义构造函数的话,编译器会使用默认构造函数,并不代表构造函数不存在。
static方法中能处理非static的属性 因为static得方法在装载class得时候首先完成,比 构造方法早,此时非static得属性和方法还没有完成初始化。。。所以不能调用
abstract类中可以有private的成员变量和方法说法正确吗 抽象类中是可以有private的属性和方法的,但是这个被private修饰的方法不能是abstract的,interface中是不允许出现非public的属性和方法的。
final类中的属性和方法都必须被final修饰符修饰,这种说法正确吗? 不对,加 final 唯一可以说明的是该类不可被继承,另外和其它类是一样的
集合考点: 集合的总结:集合包含有set,map,list特征:set是值不可重复的,map是以k-v的方式存储,再java8以前,是使用数组和链接的结合去实现map,java8以后,是链表+数组+红黑树的存储; set:HashSet/TreeSet HashSet:内部的数据结构是哈希表,是线程不安全的。他是通过hashcode方法和equal方法去保证数据的不重复 TreeSet:可以对Set集合中的元素进行排序,是线程不安全的。 元素自身具备比较功能,即自然排序,需要实现Comparable接口,并覆盖其compareTo方法。 元素自身不具备比较功能,则需要实现Comparator接口,并覆盖其compare方法。 list:vector、linklist、arrarylist map:hashmap是是链表+数组+红黑树的存储;如果大于8,就转换为红黑树,低于6转换为链表 treemap是红黑树的存储结构
搜索collection的树结构
treeset实现了自然排序的接口
treeset中,了解hashcode comparetor and equal的关系
comparetor会对treeset中的元素进行排序
java8前,该结构,如果元素都是再同一个hash值上,那么性能就大大减低
java8后,使用到了红黑树,性能大大提高,当桶值超过8后,会变成红黑树,否则是链表
它是懒加载,在使用的时候,才加载
hashmap的put方法执行过程
hash的算法
hashmap的扩容
这个方法是线程安全的,但是因为是重量级锁性能不好