Java 基础知识总结--持续更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/john_lw/article/details/71404240

Java是OOP语言,所有的OOP语言都有三个特性:封装、多态、继承。

封装

封装是一种将代码与它所处理的数据结合起来,而不被外界干扰滥用的程序设计机制。
在Java中,基本封装单元是,数据即字段,代码即方法。

多态

多态是一种允许使用一个接口来访问一类动作的特性。
在Java中,多态的表现形式为:1、接口的实现;2、继承父类进行方法重写(override);3、同一个类中进行方法的重载(overloaded)。

继承

继承是一个对象获得另一个对象的属性的过程。继承之所以重要,是因为它支持层级结构类的概念。

对象的类型,决定一类对象的外观和行为。一个类中可以设置两种类型的元素:字段方法
字段可以是任意类型的对象(基本类型和引用类型/ps:注意字段的初始化和局部变量初始化的区别);方法由名称、参数、返回值和方法体构成,其中名称和参数列表合起来称为方法签名以用来唯一的标识一个方法。
当创建类时,就是在描述那个类的对象的外观和行为。

static关键字

一个类通过new新建了对象之后,数据存储空间才会分配,其方法和域才能被外界所使用。
static关键字用来解决以下两种情形:1、只想为某特定域分配单一的存储空间,而不去考虑究竟要创建多少对象,或者根本不需要创建对象。2、希望某个方法不与包含它的类任何对象关联在一起。即使没有创建对象,也可以使用该方法。

static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法。

抽象类

抽象方法是仅有方法声明但是没有方法体的方法。包含抽象方法的类称为抽象类。抽象类是介于类和接口的中庸之道。

接口

接口是一个完全抽象的类。一方面,一个接口表示:所有实现了该接口的类看起来都像这样,这建立了类与类之间通信的协议
另一方面,接口也是其实现类的基类,类可以被向上转型为借口类型,它允许通过创建一个能够被向上转型为多种基类的类型,来实现某种类型多重继变种的特性。(一个实现了多种接口的类,其基类可以是其中任意一种。)
既然接口也是类,则满足类的基本特性:具有字段和方法。由于接口的协议特性,接口的字段和方法默认都是public的。其中字段还是static final的。
接口支持多继承。如RunnableFuture接口。

嵌套接口

接口可以嵌套在类或者其他接口中。实际上是一种内部类
由接口的协议特性,接口中的嵌套接口必须是public的。实现该外围接口无需实现嵌套接口。类中的嵌套接口可以是private的。

向上转型和向下转型

继承

1、 子类可以继承父类的非private属性和方法,不包括构造函数。属性和方法均属于类的成员,构造方法不是成员。继承描述了is-a关系,描述了两个对象的属性和行为的相似性关联性。构造函数顾名思义是用来构造一个对象的,是用来为对象的初始化服务的,并不参与对象的属性和行为的描述。
2、 子类不能继承父类的private成员,但是如果父类有protected或者public方法可以访问父类private成员,子类可以通过这些方法访问private成员。
3、 子类可以拥有自己的属性和方法。继承描述了共性,也提供了特殊性的表示方法。
4、 子类可以用自己的方式实现父类的方法—方法的重写
5、 子类可以实现父类方法的不同版本—方法的重载

对象初始化顺序

父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
当实例化子类对象时,首先要加载父类的class文件进内存,静态代码块是随着类的创建而执行,所以父类静态代码块最先被执行,子类class文件再被加载,同理静态代码块被先执行;实例化子类对象要先调用父类的构造方法,而调用父类构造方法前会先执行父类的非静态代码块

重载和重写

方法的签名:指的是方法的组成结构。具体包括方法的名称和参数,涵盖参数的数量,类型以及出现的顺序,但是不包括方法的返回值类型、访问权限修饰符、抛出的异常

初步理解:重载和重写都是多态性的表现。重载是指的同一个方法名称,但是有不同的方法签名,存在于继承和同一个类中。重写是指方法签名以及返回类型不变,抛出的异常应是被重写方法的子类,但是方法的执行逻辑变了—子类修改了父类的实现逻辑,是为重写。

方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。

try catch finally return

1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return语句执行之后,返回之前执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前就已经确定了;
4、finally中如果包含return,那么程序将在这里返回,而不是try或catch中的return返回,返回值就不是try或catch中保存的返回值了。
注意:
finally修改的基本类型是不影响返回结果的。(传值的)
修改list ,map,自定义类等引用类型时,是影响返回结果的。(传址的)对象也是传址的

内部类

https://www.cnblogs.com/dolphin0520/p/3811445.html
内部类在外部类中,类比外部类的成员变量
内部类其实和类的属性没什么区别,只是在声明的时候必须是Outer.Inner a,就像int a 一样,至于静态内部类和非静态内部类new的时候有点区别

Class对象

对应每个类的class文件,像是每个类的超级管理员。

动态方法分配

动态方法分配机制,通过该机制,对一个被重写方法的调用会在运行时解析,而不是编译时解析。是java实现运行时多态的机制。具体如:当通过超类引用调用被重写方法时,java会根据在调用发生时引用的对象的类型来判断所要执行的方法。

this关键字

this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用

class A{
    int i;
    int j;
    public A(int i){}
    public A(int i,int j){
    this(i);//调用构造器
    this.j = j;//引用属性
    }
}

基本数据类型

这里写图片描述

equals()和==

equals()是Object的方法,==是关系操作符,关系操作符计算的结果是一个boolean结果。计算的是操作数的值之间的关系。
对于基本数据类型(不是对象),equals()无法使用,通过==直接比较值。
对于引用数据类型,==和Object对象的equals()方法都是比较的对象的引用

object 的equals()方法:
public boolean equals(Object obj) {
        return (this == obj);
    }

如果想比较对象的内容,需要自己重写equals()方法。大部分java类库都实现了equals()方法,以便用来比较对象的内容,而不仅仅是引用。

String 的equals()方法:
public boolean equals(Object anObject) {
        //如果引用相同则两个String对象内容相同
        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;
    }

静态内部类和内部类

要想直接创建内部类的对象,必须先使用外部类的对象来创建该内部类对象。在拥有外部类对象之前是不可能创建内部类对象的,因为内部类对象会暗暗连接到创建它的外部类对象上去。
静态内部类则没有这个限制,可以直接创建。

public class A{
    public class B{}
    public static class C{}
}
public class Test{
    A a = new A();
    //这里不可以直接创建内部类B的对象
    //A.B b = new B();
    //正确方式,通过A的实例来创建
    A.B b = a.new B();
    //对于C,可以直接创建
    A.C c = new C();
}

Java参数传递

Java中参数传递的都是值
对于函数对参数的改变是否会影响原值的问题:

  • 值类型:传递值的拷贝,改变参数值不影响原值
  • 引用类型:传递引用的拷贝,如果参数指向了不同的实例则参数引用和原引用不相等,如果改变的是实例本身,则参数和原引用相等

equals和hashcode

equals方法用来定义两个对象实例(注意不是引用)是否相等的规则,可以理解为判断两个对象实例是否是一模一样的实例。

hashcode方法主要用在哈希表中,对象通过hashcode方法算出对象的哈希值,再去哈希表中插入或者查找。我们知道计算hashcode时是可能存在碰撞情况的,也就是不同的对象(equals),hashcode可能是一样的;但是两个对象的hashcode不一样的话,那么这两个对象一定是不相等(equals)的。

集合

List
ArrayList 数组 与System.arrayCopy
LinkedList 带头尾节点的双向链表,可以作为双端队列和栈

Map
HashMap
LinkedHashMap Entry带有前后节点的引用,带头结点的双向链表,保持插入顺序,或者在插入顺序的基础上再保持访问顺序-每次访问某个Entry,将该Entry移至链表尾部,成为最近最多使用节点(这里get方法和put方法都是如此,尤其是put方法中key已经存在了,同样会被移至链表尾部,因为recordAccess方法在HashMap中已经写在put方法里了)。启用访问顺序可以作为LRU链表使用,需要重写方法removeEldestEntry设定移除条件(如大小到了某个值),在条件达到时,即移除最近最少访问节点。

插入顺序还是访问顺序,最近最少访问节点都是链表的头结点,最近最多访问节点是链表尾节点。

TreeMap 红黑树 二叉查找树 需要比较器
WeakHashMap
ConcurrentHashMap

Set
HashSet 由HashMap支持
LinkedHashSet 由LinkedHashMap支持,遍历有序
TreeSet 由TreeMap支持,遍历有序

Queue
PriorityQueue 优先队列,由数组和堆支持。堆序性质:树的根节点小于子节点。堆序性质的维护:在叶子节点插入,上滤保持堆序;在根节点删除,下滤保持堆序。
另外还有扩容操作,直接增加容量再复制数组即可。

主要设计模式:模板方法模式、迭代器模式

并发包

AQS、ReentrantLock、ReentrantReadWriteLock、Lock、Condition、LockSupport、synchronized、volatile等

线程

定义:Callable、Runnable、Thread、Future、FutureTask、ThreadLocal
执行:Executor、Executors、ExecutorService、ThreadPoolExecutor、ScheduledExecutorService
协同:ForkJoin、CountDownLatch、中断等

并发容器

ConcurrentHashMap
阻塞队列:ArrayBlockingQueue LinkedBlockingQueue PriorityQueue(等待通知模式)
非阻塞队列:ConcurrentLinkedQueue

ThreadLocal

可以将有状态的Bean转换为无状态的Bean,如spring中的DAO,数据库连接必须是线程私有的,无法共享,通过ThreadLocal Connection将连接线程私有化。
主要通过Thread类中的ThreadLocalMap发挥作用。每个线程都有自己的ThreadLocalMap,其key为ThreadLocal对象,value为设定的值。在调用ThreadLocal的get方法获取值时,都是去当前线程的ThreadLocalMap中获取。

ThreadLocalMap中的Entry是弱引用,其弱引用是key。如果某个线程一直不死(线程池),ThreadLocalMap中的Entry将永远得不到回收。通过将key作为弱引用,帮助GC(在set和get方法中都有处理弱引用失效的Entry流程,将他它们清理出map,避免内存泄漏)。

key的hashcode值时ThreadLocalMap中的static方法生成的,同一个应用中公用这一个方法生成hashcode。该map由循环数组支持,其处理hash碰撞的方法是线性探测法。

阅读更多
换一批

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