梳理一

1、抽象类和接口的异同点?

相同点

  • 都是不断向上抽取而来的。

不同点

  • 抽象类需要被继承,而且只能单继承。接口需要被实现,而且可以多实现。
  • 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。接口中只能定义抽象方法,必须由子类去实现。
  • 抽象类的继承,是is a关系,定义该体系的基本共性内容。接口的实现是like a 关系。

注:多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。解决办法有两种,一是使用接口,一是内部类。
内部类示意:

public class Son {
    
    /**
     * 内部类继承Father类
     */
    class Father_1 extends Father{
        public int strong(){
            return super.strong() + 1;
        }
    }
    
    class Mother_1 extends  Mother{
        public int kind(){
            return super.kind() - 2;
        }
    }
    
    public int getStrong(){
        return new Father_1().strong();
    }
    
    public int getKind(){
        return new Mother_1().kind();
    }
}
2、接口回调

满足回调的两个基本条件:

  • Class A调用Class B中的X方法
  • ClassB中X方法执行的过程中调用Class A中的Y方法完成回调

一个简单的回调示意:

package com.aige.test;
/**
* @description 该类用来模拟总经理
*/
public class Manager {
/**
* @param personnel 传入一个员工类的对象
*/
public Manager(Personnel personnel) {
// 想让该让员工做什么
personnel.doSomething(this, "整理公司文件");
} /
**
* @description 当员工做完总经理让他做的事后就通过该方法通知总经理
* @param result 事情结果
*/
public void phoneCall(String result) {
System.out.println("事情" + result);
}
}

/**
* @description 该类用来模拟员工
*/
public class Personnel {
public void doSomething(Manager manager, String task) {
// 总经理通过doSomething方法告诉员工要做什么
System.out.println("总经理要你做" + task);
String result = "做完了";
// 当事情做完了我们就通过总经理公布的phoneCall方法通知总经理结果
manager.phoneCall(result);
}
}

以上例子代码简单通俗地描述了回调,但是这里我就会有这样一个疑问:假设总经理出差前交了件事情给我去办,不巧……副总经理也要给我件事去办,更无耻的是……主管也发任务过来了,都要求说做完就打电话通知他们……这时我们就要定义更多类,而且针对每个类的实现函数不一样。
最终想实现的目的就是A调用B,B实现一个处理任务的函数,处理完成后调用A中的通知函数,B可以适配所有的A。其实就是多态的思想,具体实现如下:

package com.aige.test;
/**
* @description 回调接口
*/
public interface CallBack {
// 回调方法
public void backResult(String result);
}

/**
* @description 该类用来模拟总经理
*/
public class Manager implements CallBack {
/**
* @param personnel 传入一个员工类的对象
*/
public Manager(Personnel personnel) {
// 想让该让员工做什么
personnel.doSomething(this, "整理公司文件");
} /
**
* @description 当员工做完总经理让他做的事后就通过该方法通知总经理
* @param result 事情结果
*/
public void backResult(String result) {
System.out.println("事情" + result);
}
}

/**
* @description 该类用来模拟员工
*/
public class Personnel {
public void doSomething(CallBack callBack, String task) {
// 总经理通过doSomething方法告诉员工要做什么
System.out.println("总经理要你做" + task);
String result = "做完了";
// 当事情做完了我们就通过总经理公布的phoneCall方法通知总经理结果
callBack.backResult(result);
}
}
3、异常处理

Java通 过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。


image.png

Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。
Exception(异常):是程序本身可以处理的异常。

4、String、StringBuffer、StringBuilder

5、object类

object是所有类的超类,实现了以下11个方法。继承类可以进行重写。

public final native Class<?> getClass()
public native int hashCode()
public boolean equals(Object obj)
protected native Object clone() throws CloneNotSupportedException
public String toString()
public final native void notify()
public final native void notifyAll()
public final native void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
public final void wait() throws InterruptedException
protected void finalize() throws Throwable { }

https://fangjian0423.github.io/2016/03/12/java-Object-method/

6、集合

image.png
1) list

以下几类实现了list接口。

  • LinkedList:List 接口的链接列表实现。它实现所有可选的列表操作。
  • ArrayList:List 接口的大小可变数组的实现。它实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
  • Vector:实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件

一些常用操作:
https://www.cnblogs.com/epeter/p/5648026.html

2)set

Set集合不允许重复元素,是因为Set判断两个对象相同不是使用==运算符,而是根据equals方法。
Set接口包括HashSet、TreeSet和EnumSet三个实现类。

HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等

HashMap基础
http://wiki.jikexueyuan.com/project/java-enhancement/java-twentythree.html

3) Queue

Queue接口与List、Set同一级别,都是继承了Collection接口。
Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。
如果要使用前端而不移出该元素,使用 element()或者peek()方法。
值得注意的是LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。

import java.util.LinkedList;  
import java.util.Queue;  
  
class Hello {  
    public static void main(String[] a) {  
        Queue<String> queue = new LinkedList<>();  
        queue.offer("1");//插入一个元素  
        queue.offer("2");  
        queue.offer("3");  
        //打印元素个数  
        System.out.println("queue.size()  " + queue.size());//queue.size()  3  
        //遍历打印所有的元素,按照插入的顺序打印  
        for (String string : queue) {  
            System.out.println(string);  
        }  
        System.out.println("queue.size()  " + queue.size());//queue.size()  3   上面只是简单循环,没改变队列  
  
        String getOneFrom1 = queue.element();  
        System.out.println("getOneFrom1  " + getOneFrom1);//getOneFrom1  1          因为使用前端而不移出该元素  
        System.out.println("queue.size()  " + queue.size());//queue.size()  3       队列变啦才怪  
  
        String getOneFrom2 = queue.peek();  
        System.out.println("getOneFrom2  " + getOneFrom2);//getOneFrom2  1          因为使用前端而不移出该元素  
        System.out.println("queue.size()  " + queue.size());//queue.size()  3       队列变啦才怪  
  
        String getOneFrom3 = queue.poll();  
        System.out.println("getOneFrom3  " + getOneFrom3);//getOneFrom3  1          获取并移出元素  
        System.out.println("queue.size()  " + queue.size());//queue.size()  2       队列变啦  
    }  
} 
4) Map

https://blog.csdn.net/guomutian911/article/details/45771621
对hashmap讲解的比较详细
map或者HashSet都会对添加的元素进行判重,但如何判断呢,有以下机制:
两个对象的哈希码相同并且(两个对象是同一个对象或者两个对象相等[equals为true])

7、基本类型和包装类

http://alexyyek.github.io/2014/12/29/wrapperClass/

public static void main(String[] args){
    Integer i = 10; //装箱
    int index = i;  //拆箱
}

上面是自动装箱和拆箱,本质上,装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的xxxValue方法实现的。(xxx代表对应的基本数据类型)。


==和equals区别

分析下面的结果:

public class Main {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        
        System.out.println(i1==i2);  // true
        System.out.println(i3==i4);  // false
    }
}

第一个为true说明两个指向同一个对象,为什么呢,从下面代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在 [-128,127] 之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

而对于double类

public class Main {
    public static void main(String[] args) {
        Double i1 = 100.0;
        Double i2 = 100.0;
        Double i3 = 200.0;
        Double i4 = 200.0;
        
        System.out.println(i1==i2); // false
        System.out.println(i3==i4); // false
    }
}

具体为什么,读者可以去查看Double类的valueOf的实现。
在这里只解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的,Double、Float的valueOf方法的实现是类似的。

public class Main {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        Long h = 2L;
         
        System.out.println(c==d);
        System.out.println(e==f);
        System.out.println(c==(a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g==(a+b));
        System.out.println(g.equals(a+b));
        System.out.println(g.equals(a+h));
    }
}
true
false
true
true
true
false
true

第一个和第二个输出结果没有什么疑问。第三句由于 a+b 包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。而对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。同理对于后面的也是这样,不过要注意倒数第二个和最后一个输出的结果(如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法)。

8、 泛型

参考
https://blog.csdn.net/s10461/article/details/53941091
先看看简单的泛型

class Point<T>{// 此处可以随便写标识符号   
    private T x ;        
    private T y ;        
    public void setX(T x){//作为参数  
        this.x = x ;  
    }  
    public void setY(T y){  
        this.y = y ;  
    }  
    public T getX(){//作为返回值  
        return this.x ;  
    }  
    public T getY(){  
        return this.y ;  
    }  
};  

不难理解,泛型就是一种类似于模版的语法,当不确定传入的参数时就可以使用。

字母规范

 E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
 K,V — Key,Value,代表Map的键值对
 N — Number,数字
 T — Type,类型,如String,Integer等等

泛型好处:

  • 提高安全性: 将运行期的错误转换到编译期. 如果我们在对一个对象所赋的值不符合其泛型的规定, 就会编译报错.
  • 避免强转: 比如我们在使用List时, 如果我们不使用泛型, 当从List中取出元素时, 其类型会是默认的Object, 我们必须将其向下转型为String才能使用。比如:
List l = new ArrayList();
l.add("abc");
String s = (String) l.get(0);

而使用泛型,就可以保证存入和取出的都是String类型, 不必在进行cast了。比如:

List<String> l = new ArrayList<>();
l.add("abc");
String s = l.get(0);

9、static 和 final

1)static

Java把内存分为栈内存和堆内存,其中栈内存用来存放一些基本类型的变量、数组和对象的引用,堆内存主要存放一些对象。在JVM加载一个类的时候,若该类存在static修饰的成员变量和成员方法,则会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域,有了这些“固定”的特性,那么JVM就可以非常方便地访问他们。
值得注意的是对象的static修饰的成员变量和方法是类属性,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。所有实例的引用都指向同一个地方,任何一个实例对其的修改都会导致其他实例的变化。
下面程序:

class staticCode {
    static String school;
    static {
        school = "hello";
        System.out.println("nice to meet you");
    }
    public void hello(){
        System.out.println("hello boy");
    }
}
public class testDemo {
    public static void main(String[] args) {
        staticCode s = new staticCode();
        new staticCode();
        s.hello();
    }
}

输出:

nice to meet you
hello boy

上面创建了两个对象,但是“nice to meet you”只打印了一次,说明静态变量和方法是所有实例共享的,只初始化一次。
更多理解参考

2) final
  • 修饰类,当用final修饰一个类时,表明这个类不能被继承。
  • 修饰方法,防止任何继承类对他的修改。private也有类似的作用。
  • 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = "hello";
        String d = "hello";
        String c = b + 2; 
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}

上面程序第一个打印为true,第二个打印为false。
补充:

public class testDemo {
    public static void main(String[] args) {
        String d = "hello";
        String c = "helloworld";
        String e = "hello" + "world";
        String f = d + "world";
        System.out.println(e==c);
        System.out.println(f == c);
    }
}

上面的输出也是 true和false。
对于那些在编译时就能确定的字面量都会存放在运行时常量池中,比如:
String c = "hello " + "world"; //JVM会将此代码优化为String c = "hello world";
String d = "hello world";
常量池中的变量是固定的,不可修改的,因此对e来说,编译阶段确定了是“helloworld”,会先在常量池中寻找看有没有,如果有,直接返回地址,如果没有就会新开辟一块区域。因此e和c是相等的。
而如下代码
String b = a + "world";
其中a是变量,在编译时不能确定值,所以不会被放在运行时常量池中,而是在堆中重新new了一块儿内存。

再回到第一个代码段,对用final修饰的变量,JVM在编译时,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此上面两个程序段就有点类似了。

10、 存在继承初始化顺序

存在继承的情况下,初始化顺序为:
父类(静态变量、静态语句块)
子类(静态变量、静态语句块)
父类(实例变量、普通语句块)
父类(构造函数)
子类(实例变量、普通语句块)
子类(构造函数)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 这一周的学习分享会我们学习了稻盛和夫所著《活法》一书中的三个小节,其中“对领导的要求是德重于才”这一点很...
    牛妈牛妈阅读 5,782评论 0 1
  • 所以享受过程吧,让所有不确定性都随风而去。过去的我试着某些路径来抑制不确定性,后来发现选择并不是自由的,现在回头看...
    lan348561阅读 743评论 0 1
  • 这本《如何说孩子才肯学》被美国《儿童》杂志评为“家庭教育年度最佳图书”,中文版于2008年首次出版。作者叫做阿黛尔...
    杨泽阅读 825评论 2 1