Java秋招复习之01. JavaSE知识点复习

个人觉得这篇博客总结得不错, 就把它作为目录来一点一点地去学习和扩展,
秋招Java岗位技能表
https://blog.csdn.net/jsj13263690918/article/details/80558008

JavaSE

 1. 字符串
 2. 接口和抽象类
 3. 内部类
 4. 异常
 5. 泛型
 6. 反射

18.07.16
今天先总结1-2的知识点, 个人也会结合源码来慢慢分析!

1. 字符串

首先, String 是value不可改变的,
同时String类还使用了final来修饰,表明String的第二个重要特性,String是不可被继承的
关于String,StringBuffer,StringBuilder的区别
String是值不可变的,每次进行连接操作是都是返回一个新的String对象,StringBuffer,StringBuilder是值可变的,操作是返回的是this
这也就是为什么在进行大量字符串连接运算时,不推荐使用String,而推荐StringBuffer和StringBuilder。
StringBuffer是线程同步的,安全性高,但执行效率低
StringBuilder是非线程同步的,安全性低,但执行效率高
同步实现的方式其实就是在append方法上加了synchronized关键字
image.png

补充:
针对==的总结如下
众所周知,==是判断内存地址的,那么我们判断的话看引用最终指向哪里不就可以了么.

new出来的对象是存放在堆内存中的,引用指向堆内存,那么地址肯定是唯一的了,所以结果肯定为false
直接声明的字符串引用是指向常量池的,而常量池中的相同内容的字符串只有一份,所以结果为true
通过+号连接的字符串分如下两种情况
3.1 如果+号两边连接的是常量,那么会在编译期间进行优化
image.png
使用IDEA自带的class反编译器打开:
image.png

3.2 如果+号两边连接的有变量,不管是new出来的也好,直接声明的也好,java虚拟机执行的时候都会生成一个StringBuilder对象sb,然后调用sb.apend()方法,最后通过sb.toString()返回一个新的字符串。那么此时引用就指向堆内存, 这里指向的地址就不相等了.
image.png

同时, 补充一下字符串的常用方法:
https://blog.csdn.net/menglanyingfei/article/details/60869212

2. 接口和抽象类

image.png

https://www.zhihu.com/question/20149818
目的:
Java也叫做C++–
Java于是禁止class的多继承,引入了interface的概念,
interface只是定义了行为特性的规约,没有实现,因此不会有二义性。

设计层面上:
接口是对动作的抽象,而抽象类是对事物的本质(类别)的抽象
对于抽象类,比如男人,女人这两个类,那我们可以为这两个类设计一个更高级别的抽象类–人。
对于接口,我们可以坐着吃饭,可以站着吃饭,可以用筷子吃饭,可以用叉子吃饭,那么可以把这些吃饭的动作抽象成一个接口 – 吃饭。
所以在高级语言中(如Java, C#),一个类只能继承一个抽象类(因为你不可能同时是生物又是非生物)。
但是一个类可以同时实现多个接口,比如开车接口,踢足球接口,游泳接口。

3. 内部类

成员内部类、局部内部类、匿名内部类、静态内部类
这篇写得非常好, 所以直接引用一下!
https://www.cnblogs.com/chenssy/p/3388487.html

4. 异常

Throwable
|-Error
|-Exception
    |-RuntimeException

5. 泛型

PECS原则
上面我们看到了类似<? extends T>的用法,利用它我们可以从list里面get元素,那么我们可不可以往list里面add元素呢?我们来尝试一下:

public class GenericsAndCovariance {
    public static void main(String[] args) {
        // Wildcards allow covariance:
        List<? extends Fruit> flist = new ArrayList<Apple>();
        // Compile Error: can't add any type of object:
        // flist.add(new Apple())
        // flist.add(new Orange())
        // flist.add(new Fruit())
        // flist.add(new Object())
        flist.add(null); // Legal but uninteresting
        // We Know that it returns at least Fruit:
        Fruit f = flist.get(0);
    }
}

答案是否定,Java编译器不允许我们这样做,为什么呢?对于这个问题我们不妨从编译器的角度去考虑。因为List

List<? extends Fruit> flist = new ArrayList<Fruit>();
List<? extends Fruit> flist = new ArrayList<Apple>();
List<? extends Fruit> flist = new ArrayList<Orange>();

当我们尝试add一个Apple的时候,flist可能指向new ArrayList();
当我们尝试add一个Orange的时候,flist可能指向new ArrayList();
当我们尝试add一个Fruit的时候,这个Fruit可以是任何类型的Fruit,而flist可能只想某种特定类型的Fruit,编译器无法识别所以会报错。
所以对于实现了<? extends T>的集合类只能将它视为Producer向外提供(get)元素,而不能作为Consumer来对外获取(add)元素。

如果我们要add元素应该怎么做呢?可以使用<? super T>

public class GenericWriting {
    static List<Apple> apples = new ArrayList<Apple>();
    static List<Fruit> fruit = new ArrayList<Fruit>();
    static <T> void writeExact(List<T> list, T item) {
        list.add(item);
    }
    static void f1() {
        writeExact(apples, new Apple());
        writeExact(fruit, new Apple());
    }
    static <T> void writeWithWildcard(List<? super T> list, T item) {
        list.add(item)
    }
    static void f2() {
        writeWithWildcard(apples, new Apple());
        writeWithWildcard(fruit, new Apple());
    }
    public static void main(String[] args) {
        f1(); f2();
    }
}

这样我们可以往容器里面添加元素了,但是使用super的坏处是以后不能get容器里面的元素了,原因很简单,我们继续从编译器的角度考虑这个问题,对于List<? super Apple> list,它可以有下面几种含义:

List<? super Apple> list = new ArrayList<Apple>();
List<? super Apple> list = new ArrayList<Fruit>();
List<? super Apple> list = new ArrayList<Object>();

当我们尝试通过list来get一个Apple的时候,可能会get得到一个Fruit,这个Fruit可以是Orange等其他类型的Fruit。

根据上面的例子,我们可以总结出一条规律,”Producer Extends, Consumer Super”:

“Producer Extends” – 如果你需要一个只读List,用它来produce T,那么使用? extends T。
“Consumer Super” – 如果你需要一个只写List,用它来consume T,那么使用? super T。
如果需要同时读取以及写入,那么我们就不能使用通配符了。
如何阅读过一些Java集合类的源码,可以发现通常我们会将两者结合起来一起用,比如像下面这样:

public class Collections {
    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        for (int i=0; i<src.size(); i++)
            dest.set(i, src.get(i));
    }
}

http://www.importnew.com/24029.html

6. 反射

反射(reflection)允许静态语言在运行时(runtime)检查、修改程序的结构与行为。
什么是java反射机制?我们又为什么要学它?
当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射。
IT行业里这么说,没有反射也就没有框架,现有的框架都是以反射为基础。
通过getParameterTypes()方法只能获取方法的参数类型,而无法获取参数名
https://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

参考

https://www.jianshu.com/p/8c161bb213c6
http://www.importnew.com/12399.html

阅读更多
版权声明:本文为 梦蓝樱飞 原创文章,可以随意转载,但真诚希望在明确位置注明原文超链接的出处!!! 非常感谢! https://blog.csdn.net/menglanyingfei/article/details/81066437
文章标签: 秋招
个人分类: Java基础
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭