2020.11.30记录
目录
抽象类与接口相关
考点:抽象类与接口
抽象类和接口都能实例化的(X)
抽象类不能实例化,需要靠子类继承并重写所有的抽象方法。
抽象类不能实现接口(X)
是可以的
抽象类方法的默认访问权限默认都是public(X)
抽象类的默认访问权限都是default。
抽象类不能用private、static、synchronized、native访问修饰符。
接口方法的访问权限默认是public(√)
有且只能默认public。
考点:接口与类
类是只能单继承的,而接口是多继承的。
如果类A,继承了B和C,而B和C都有相同的方法,那么类A就不知道继承哪个实现。
但是接口是没有实现的,接口不能实现接口,只能继承接口,因此也不会有上述的问题出现。
接口的修饰符
接口中字段的修饰符:public static final(默认不写)
接口中方法的修饰符:public abstract(默认不写)
线程同步问题
考点:wait()方法的使用
void waitForSignal()
{
Object obj = new Object();
synchronized(Thread.currentThread())
{
obj.wait();
obj.notify();
}
}
- wait方法要用try/catch包裹,或者抛出InterruptedException。
- synchronized的目标与wait方法的物件不相同,会有IllegalMonitorStateException。
这里使用的是run,而非start,因此并没有开启新的线程,依旧是主线程在跑。
考点:yield和Join是否释放了锁?
在Java中,只有wait会释放锁资源,而Join底层是用wait来实现了,所以join也能释放锁。
yield则是告诉CPU可以让出时间片,让其他线程来跑,但如果自己是有锁的,依旧只有自己能跑。
包装类和基本数据类型
== 比较的是 两边的地址
当两边都是基本数据类型的时候,比较的是两边的值。
当一边是包装类型,一边是基本数据类型是,就要将包装类型进行拆包。
当两边都是包装类型的时候,比较的就是地址。
因此 C一定是错的。
强制类型转换
byte b1=1,b2=2,b3,b6;
final byte b4=4,b5=6;
b6=b4+b5;
b3=(b1+b2);
System.out.println(b3+b6);
在Java中,byte、short、char运算之后都会自动转换成Int,除非有final修饰。
所以第四行中,b1+b2已经变成int类型了,因此要赋值给b3的时候就要强制类型转换。
Java的类加载器
大致分为两类:
- 系统提供的
- Java应用开发人员编写的
系统提供的有下面三个:
-
引导类加载器(bootstrap class loader)
它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。 -
扩展类加载器(extensions class loader)
它用来加载 Java 的扩展库。Java虚拟机的实现会提供一个扩展库目录,扩展类加载器在此目录里面查找并加载 Java 类(主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。)
-
系统类加载器(system class loader)
它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。
开发人员可以继承java.lang.ClassLoader类的方式来实现自己的类加载器。
体现了Java动态实时装入特性。
导包
package ch4;
此行语句不是导包,而是将这个类放入到/ch4这个文件夹中
import ch4.*;
此行语句为导包。
静态变量
class HasStatic{
private static int x = 100;
public static void main(String args[ ]){
HasStatic hs1 = new HasStatic();
hs1.x++;
HasStatic hs2 = new HasStatic();
hs2.x++;
hs1=new HasStatic();
hs1.x++;
HasStatic.x--;
System.out.println( "x=" +x);
}
}
在这里,虽然类中定义了静态私有变量,但是因为他是静态的,不属于任何一个实例对象,因此是可以调用的。
try/catch
try后面必须有catch(x)
catch和finnally两者可以省略其一,但是不能两者都省略。
finnally是必定访问的。
如果try语句中有return。
- 如果有返回值,就把返回值保存到局部变量中;
- 执行jsr指令跳到finally语句里执行;
- 执行完finally语句后,返回之前保存在局部变量表里的值。
如果try,finally语句里均有return,忽略try的return,而使用finally的return.
JSP
1、JSP分页
先取总记录数,得到总页数,最后显示本页的数据。
总页数=总记录数/每页显示的条数
2、JSP内置错误处理
在 myjsp.jsp 中,关于下面的代码说法错误的是: ( A )
<%@ page language=“java” import=“java.util.*” errorPage=“error.jsp” isErrorPage=“false” %>
A。该页面可以使用 exception 对象
B。该页面发生异常会转向 error.jsp
C。存在 errorPage 属性时,isErrorPage 是默认为 false
D。error.jsp 页面一定要有isErrorPage 属性且值为 true
exception是JSP九大内置对象之一,其实例代表其他页面的异常和错误。只有当页面是错误处理页面时,即isErroePage为 true时,该对象才可以使用。
errorPage的实质就是JSP的异常处理机制,发生异常时才会跳转到 errorPage指定的页面,没必要给errorPage再设置一个errorPage。所以当errorPage属性存在时, isErrorPage属性值为false,即无法使用excption对象。
Java基本数据类型的长度和默认值
Java的继承(重点)
在Java中,继承对构造函数是不继承的,只是显式和隐式的调用。
在Java中子类的构造器默认第一行都会有隐式的super()。
尽管没有写这一条语句。
如果父类没有无参构造函数,那么子类需要显示调用父类的有参构造函数。
构造器里面可以调用其他方法的。
class Base{
public Base(String s){
System.out.print("B");
}
}
public class Derived extends Base{
public Derived (String s) {
System.out.print("D");
}
public static void main(String[] args){
new Derived("C");
}
}
这里的编译直接就会出错。
原因是因为父类没有无参构造方法,而子类缺没有显式调用有参构造函数的父类。
GC垃圾回收的标准
在Java中判断一个内存空间符合垃圾回收的标准。
- 给对象引用置为null,回收没有对象引用指向的对象
- 对对象引用置为new的对象,回收没有对象引用指向的对象。
Java的字符编码
char类型在Java中使用的是Unicode编码,占用两个字节,不仅可以存储ASCII码,还可以存储一个汉字。
Java集合
public static void main(String args[]) {
List Listlist1 = new ArrayList();
Listlist1.add(0);
List Listlist2 = Listlist1;
System.out.println(Listlist1.get(0) instanceof Integer);
System.out.println(Listlist2.get(0) instanceof Integer);
}
在Java中的Collection对象只能装入对象。
在JDK1.5之后,支持自动装箱,因此add(0)会把0封装成一个Integer,编译通过。
List没有使用泛型,得到的对象是一个Object类型,但是运行类型是Integer,所以打印了true。
异常的抛出
public void getCustomerInfo() {
try {
// do something that may cause an Exception
} catch (java.io.FileNotFoundException ex) {
System.out.print("FileNotFoundException!");
} catch (java.io.IOException ex) {
System.out.print("IOException!");
} catch (java.lang.Exception ex) {
System.out.print("Exception!");
}
}
无论如何处理,都只会抛出一个异常,而不是多个异常一起抛出。