• java基础(面向对象,异常,类,抽象类,继承类,构造方法,接口,string类,==和equals,修饰符final,static,重写和重载)


    JAVA中抽象类和接口有什么区别

    不同
    抽象类:
    1.抽象类中可以定义构造器
    2.可以有抽象方法和具体方法
    3.接口中的成员全都是public的
    4.抽象类中可以定义成员变量
    5.有抽象方法的类必须声明为抽象类,而抽象类未必要有抽象方法
    6.抽象类中可以包含静态方法
    7.一个类只能继承一个抽象类

    接口:
    1.接口中不能定义构造器
    2.方法全都是抽象方法
    3.抽象类中的成员可以是private,默认,protected,public
    4.接口中定义的成员变量实际上是常量
    5.接口中不能有静态方法
    6.一个类可以实现多个接口

    Java中==和equals有哪些区别

    equals和==最大的区别是一个是方法一个是运算符

    ==:如果比较的对象时基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等
    equals(): 用来比较两个方法的内容是否相等。
    注意:equals方法不能用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向二代对象的地址。

    ● == : 对比的是栈中的值,基本数据类型是变量值,引用数据类型是堆中内存对象的地址;
    直接比较的两个对象的堆内存地址,如果相等,则说明这两个引用实际是指向同一个对象地址的
    ● equals:object中默认也是采用==比较,通常会重写

    == 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.

    Java中重写和重载有哪些区别

    方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性,重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同,参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法生命更多的

    String ,StringBuffer,StringBuilder区别及使用场景

    Java平台提供了两种类型的字符串:String和StringBuilder,它们都可以存储和操作字符串,区别如下。

    1.String是只读字符串,也就意味着String引用的字符串内容是不能被改变的,初学者可能会有这样的误解:

    String str ="abc";
    str = "bad"
    
    • 1
    • 2

    如上,字符串str命名是可以改变的吖!其实不然,str仅仅是一个是一个引用对象,它指向一个字符串对象“abc”,
    第二行代码的含义是让str重新指向一个新的字符串"bcd"对象,而“abc”对象并没有任何改变,只不过该对象已经成为了一个不可及对象罢了

    2.StringBuffer/StringBuffer表示的字符串对象可以直接修改
    3.StringBuffer是java5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方法都没有被synchronized修饰,因此它的效率理论上也比StringBuffer要高。

    JAVA接口

    为什么要用接口

    接口被用来描述一种抽象。因为JAVA不像C++一样支持多继承,所以JAVA可以通过实现接口来弥补这个局限
    接口也可以用来实现解耦。
    接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,接口的静态成员变量要用static final public 来修饰
    \接口中的方法都是抽象的,是没有方法体的,可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。

    可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法。(JDK1.8之前可以这样理解)

    和抽象类区别:

    ● 抽象类实例化是变量指向实现抽象方法的子类对象,接口变量必须实现所有接口方法的类对象
    ● 抽象类要被子类继承,接口被类实现
    ● 接口只能做方法申明,抽象类可以做方法实现
    ● 接口定义的变量只能是公共的静态的常量,抽象类中是普通变量
    ● 接口可以通过匿名内部类实例化

    ● 一个抽象类可以是public、private、protected、default,接口只有public;
    ● 一个抽象类中的方法可以是public、private、protected、default,接口中的方法只能是public和default
    ● abstract不能与final并列修饰同一个类;abstract 不能与private、static、final或native并列修饰同一个方法
    ● 抽象方法不能有方法体,抽象方法不能使用private修饰符,也不宜使用默认修饰符(default)接口 不可以实例化 。 通过接口实现类创建对象

    JAVA构造方法

    构造方法的声明:
    修饰符 class_name(类名)  (参数列表){
     逻辑代码
    }
    
    • 1
    • 2
    • 3
    • 4
    1. 构造⽅法的⽅法名和类名⼀致(包括⼤⼩写)
    2. 构造⽅法没有返回值类型(连void都没有)
    3. 构造⽅法可以重载
    4. 构造⽅法不可以⼿动调⽤,只能在创建对象的时,jvm⾃动调⽤
    5. 构造⽅法在创建对象时只能调⽤⼀次
    6. 构造⽅法的⽅法名和类名⼀致(包括⼤⼩写)
    7. 构造⽅法没有返回值类型(连void都没有)
    8. 构造⽅法可以重载
    9. 构造⽅法不可以⼿动调⽤,只能在创建对象的时,jvm⾃动调⽤
    10. 构造⽅法在创建对象时只能调⽤⼀次

    当⼀个类中,没有定义构造⽅法 系统会⾃动提供⼀个公开的 ⽆参的构造⽅法 当类中已经定义了构 造⽅法,系统不再提供⽆参公开构造,如果需要使⽤⽆参的构造 那么必须⾃⼰定义出来 ⼀般开发如果 定义了有参的构造 都会再定义⼀个⽆参的构造

    构造方法不能被 static、final、synchronized、abstract 和 native(类似于 abstract)修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。

    构造函数的作用是创建一个类的实例。用来创建一个对象,同时可以给属性做初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。

    static的作用

    static修饰的变量没有发生变化是因为static作用于成员变量只是用来表示保存一份副本,其不会发生变化。怎么理解这个副本呢?其实static修饰的在类加载的时候就加载完成了(初始化),而且只会加载一次也就是说初始化一次,所以不会发生变化!

    static是不允许用来修饰局部变量 静态变量只能在类主体中定义,不能在方法中定义

    ● 静态变量:
    静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中JVM只为静态变量分配一次内存空间。
    ● 实例变量:
    每次创建对象都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量。

    super的作用

    ● 调用父类被子类重写的方法;
    ● 调用父类被子类重定义的字段(被隐藏的成员变量);
    ● 调用父类的构造方法;

    如果子类没有重写父类的方法,调用父类的方法用不用super关键字结果都一样。 如果子类重写父类的方法,调用父类的方法必须用super关键字

    String的底层存储是什么?

    在JDK9之前,String的底层存储结构是char[],一个char需要占用两个字节的存储单位

    sleep()与wait()区别?

    区别1:使用限制
    使用 sleep 方法可以让让当前线程休眠,时间一到当前线程继续往下执行,在任何地方都能使用,但需要捕获 InterruptedException 异常。

    try {
    Thread.sleep(3000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    而使用 wait 方法则必须放在 synchronized 块里面,同样需要捕获 InterruptedException 异常,并且需要获取对象的锁。

    synchronized (lock){
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    而且 wait 还需要额外的方法 notify/ notifyAll 进行唤醒,它们同样需要放在 synchronized 块里面,且获取对象的锁。。

    synchronized (lock) {
    // 随机唤醒
    lock.notify();

    // 唤醒全部
    lock.notifyAll();
    
    • 1
    • 2

    }
    当然也可以使用带时间的 wait(long millis) 方法,时间一到,无需其他线程唤醒,也会重新竞争获取对象的锁继续执行。

    区别2:使用场景
    sleep 一般用于当前线程休眠,或者轮循暂停操作,wait 则多用于多线程之间的通信。

    区别3:所属类
    sleep 是 Thread 类的静态本地方法,wait 则是 Object 类的本地方法。

    java.lang.Thread#sleep
    public static native void sleep(long millis) throws InterruptedException;
    java.lang.Object#wait
    public final native void wait(long timeout) throws InterruptedException;
    为什么要这样设计呢?

    因为 sleep 是让当前线程休眠,不涉及到对象类,也不需要获得对象的锁,所以是线程类的方法。wait 是让获得对象锁的线程实现等待,前提是要楚获得对象的锁,所以是类的方法。

    区别4:释放锁
    Object lock = new Object();
    synchronized (lock) {
    try {
    lock.wait(3000L);
    Thread.sleep(2000L);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    如上代码所示,wait 可以释放当前线程对 lock 对象锁的持有,而 sleep 则不会。

    区别5:线程切换
    sleep 会让出 CPU 执行时间且强制上下文切换,而 wait 则不一定,wait 后可能还是有机会重新竞争到锁继续执行的。

  • 相关阅读:
    【C++进阶】:AVL树(平衡因子)
    数据结构之图
    基于PHP+MySQL大学宿舍管理系统的设计与实现
    夏洛克和他的女朋友—线性筛—逻辑
    Database之SQL:SQL在线编程、工作中常用SQL代码实践(以语法为导向的增、删、改、查,已基本涵盖所有语法案例)之详细攻略
    FPGA常用通信协议 —UART(二)---UART接收
    中秋味的可视化大屏 【以python pyecharts为工具】
    devops自动化运维平台的核心原则有哪些?
    C语言题解 | 消失的数字&轮转数组
    MySql计算多个表的数据总行数
  • 原文地址:https://blog.csdn.net/weixin_43847969/article/details/125610027