| 接口和抽象类所谓抽象类,其实是对一种事物的抽象。例如,给出两个动物,猫和狗,我们需要一个类来描述这两种动物,但是他们特性不同,所以可以将这个类设计为抽象类。而接口是对一种行为的抽象,例如,猫和狗都有叫声这个行为,但是具体实现又不同,所以将这个方法设计为接口,用到时再具体实现。 抽象类1.抽象类和抽象方法都要用abstract修饰2.抽象方法必须在抽象类中,抽象类中可以没有抽象方法
 3.抽象类不能直接创造对象(实例化)
 4.抽象类的子类如果重写所有抽象方法,那么就是一个具体的类。抽象类的子类不重写所有抽象方法,那么子类还是一个抽象类。
 使用:实例类 extends 抽象类{} 接口1.使用interface修饰2.接口不能实例化对象
 3.修饰抽象方法 public abstract 修饰常量 public static final
 4.使用:class Test implements 接口1,接口2,接口3
 异同 相同点 :
 1.他俩都不能实例化对象
 2.可以包含抽象方法
 3.定义好的抽象方法要求子类强制重写
 不同点:
 1.接口中的属性只能定义成静态常量,抽象类当中的属性是最普通的属性
 2.接口中只有public权限,抽象类当中可以包含四种权限
 3.接口中的抽象方法不用abstract修饰,抽象类当中必须使用abstract
 4.抽象类可以包含普通方法和抽象方法,但是接口只能包含抽象方法
 5.接口不能定义构造函数,抽象类可以
 6.接口可以进行多继承,多实现,抽象类只能单继承
 7.定义的关键字和实现的关键字都不一样 接口(interface implements)
 异常定义:在程序运行过程中出现的错误,称为异常。异常就是程序运行过程中出现了不正常现象导致程序的中断。1.常见异常
 NullPointerException(空指针异常,要访问的变量没有引用任何对象时,抛出该异常)ArrayIndexOutOfBoundsException (下标越界异常)使用数组,尤其是做for循环判断条件的时候,很容易引发的一个问题。IndexOutOfBoundsExcention 索引越界异常,由于数组下标越界或字符串访问越界引起异常;SQLException 操作数据库异常
 2.继承层次
  如图,上图为Java中异常的体系结构,而Throwable类也继承于Object类。而后又分为Error和Exception两大类。异常又分为运行时异常和非运行时异常。
 3.异常处理机制
 关键字:
 try:用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。catch:用于捕获异常。catch用来捕获try语句块中发生的异常finally: finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。throw:用于抛出异常throws:用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。
 try{可能发生异常的代码
}catch(关心异常具体类,不关心基类处理){
}finally{无论代码是否会发生异常,必定会被执行
System.exit(1);(这种情况除外)
}
 Object类中的方法clone方法:保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常getClass方法:final方法,获得运行时类型toString方法:用的较多,一般子类对其进行重写finalize方法:用于释放资源,因为无法确定该方法什么时候被调用,很少使用。equals方法:该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法hashCode方法:该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。wait方法:wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。调用该方法后当前线程进入睡眠状态,直到以下事件发生。(1)其他线程调用了该对象的notify方法。
 (2)其他线程调用了该对象的notifyAll方法。
 (3)其他线程调用了interrupt中断该线程。
 (4)时间间隔到了。
 此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
notify方法该方法唤醒在该对象上等待的某个线程。
notifyAll方法该方法唤醒在该对象上等待的所有线程。
 为什么要同时重写equals和hashcode方法? 以下是关于hashcode的一些规定: 两个对象相等,hashcode一定相等 两个对象不等,hashcode不一定不等 hashcode相等,两个对象不一定相等 hashcode不等,两个对象一定不等
 假如只重写equals而不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。 然而重写了equals,且s1.equals(s2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从Student类重写后的hashcode方法中可以看出,重写后返回的新的哈希值与Student的两个属性有关。
 类加载类加载时机:1.new 对象
 2.类名.static成员
 3.反射: Class.forName(“People”)
 4.main函数所在的类优先被加载
 class TestDemo{
 public static void main(String[] args){
 }}
 5.先初始化父类 在初始化子类
 类的初始化顺序 :静态变量→静态块→实例变量→实例块→构造函数。
 子类的初始化顺序:父类 静态变量 父类静态块子类 静态变量 子类静态块
 父类的实例变量 实例块 构造
 子类的实力变量 实例块 构造
 类加载过程
 双亲委派模型
 反射 
 概述:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 一般情况下 拿到当前类的Class对象有下面四种方式Class<?> c = People.class;
 People p = new People();
 Class<?> c = p.getClass();
 Class<?> c = Class.forName(“People”)
 一个正常的类加载过程是这样的:
 
  而反射通过Class对象 获取构造方法 生成当前类的对象 优点:在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。 缺点:(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
 String类 jdk1.84.1 实现以及相关方法String字符串对象本质是一个final修饰的字符数组对象。因为被final修饰,所以字符串是常量,它们的值一旦被创建后不能改变。同样String类也不能被继承。
  常用方法
 使用字符数组创建String对象
  public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
 获取指定下标位置的元素  public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }
 获取字符串长度  public int length() {
        return value.length;
    }
 转化为字节数组 public byte[] getBytes(String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null) throw new NullPointerException();
        return StringCoding.encode(charsetName, value, 0, value.length);
    }
 4.2 字符串拼接”hello“ + ”world“ 和 s + ”world“的区别 +运算符如果一边是变量的话就会 先查找常量池中有没有拼接完的 如果有常量池就不会在新建 否则会新建一个常量 最后会在堆中创建一个新的String对象。也就是说s+”world“在拼接时原来的s对象并没有改变,只是s在拼接完成后会指向新创建的String对象引用。 如果二端都是常量 先查找常量池中有没有拼接完的 如果有常量池就不会在新建 否则会新建一个常量 但不会在堆中创建新的对象 4.3 字符串比较 “==”和“equals”什么是==?== 等于比较运算符,如果进行比较的两个操作数都是数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true.如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成 ==比较的是两个变量的内存地址)
 什么是equals?equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.
 区别== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.
 Object中的equals
 public boolean equals(Object obj) {
        return (this == obj);
    }
 String中的equals public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
 可以看到String类是重写了equals的方法的 4.4 string、stringbuffer、stringbuilder的区别首先,三者的共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。其次区别在于 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。运行速度快慢为:StringBuilder > StringBuffer > String
 总的来说:String:适用于少量的字符串操作的情况
 StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
 StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
 |