目前在学习JAVA面向对象中遇到问题汇总(三)


前言

目前有几个待解释的问题。
①包装类的总结。这里主要引用了(包装类和基本类型
②“==”和equals的区别(java中==和equals的区别是什么?
③重载与重写的区别(参考了这篇)
④子类与父类其中构造函数调用的顺序
子类的构造器是一定要调用父类的构造器吗?
⑤JVM架构和GC垃圾回收机制

这里记录了一些在笼统看了尚硅谷的讲义,所面临的基础问题。所以,在这里总结了一下网上的资料并解释


一、包装类的总结

所谓包装类,就是能够直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类。

1.1包装类的组成

在这里插入图片描述

1.2包装类的用途

总之:可以引入一些包装类的基本操作。
1.集合不允许存放基本数据类型,故常用包装类
2.包含了每种基本类型的相关属性,如最大值,最小值,所占位数等
3.作为基本数据类型对应的类类型,提供了一系列实用的对象操作,如类型转换,进制转换等

1.3基础类型,包装类,字符串之间的转换

基本类型与包装类之间转换
基本类型与字符串之间的转换

1.4基本类型与包装类型的区别

1、在Java中,一切皆对象,但八大基本类型却不是对象。(为了数据在Java中的统一)
2、声明方式的不同,基本类型无需通过new关键字来创建,而封装类型需new关键字。
3、存储方式及位置的不同,基本类型是直接存储变量的值保存在堆栈中能高效的存取,封装类型需要通过引用指向实例,具体的实例保存在中。
4、初始值的不同,封装类型的初始值为null,基本类型的的初始值视具体的类型而定,比如int类型的初始值为0,boolean类型为false;
5、使用方式的不同,比如与集合类合作使用时只能使用包装类型。
6、什么时候该用包装类,什么时候用基本类型,看基本的业务来定:这个字段允允许null值,就需要使用包装类型,如果不允许null值,,使用基本类型就可以了,用到比如泛型和反射调用函数,就需要用包装类!

ublic class TestInteger {
    public static void main(String[] args) {
        int i = 128;
        Integer i2 = 128;//这里是128,不能直接进行缓存。其缓存范围为-128到127之间
        Integer i3 = new Integer(128);
        System.out.println(i == i2); //Integer会自动拆箱为int,所以为true
        System.out.println(i == i3); //true,理由同上
        Integer i4 = 127;//编译时被翻译成:Integer i4 = Integer.valueOf(127);
        Integer i5 = 127;//由于直接缓存,在127已经有的情况下,会直接指向上一个已经存在地址
        System.out.println(i4 == i5);//true  所以i4与i5其实指的是同一个地址
        Integer i6 = 128;//这里是128,不能直接进行缓存。其缓存范围为-128到127之间。而是相当于 Integer i6 = new Integer(128),放在堆里。
        Integer i7 = 128;
        System.out.println(i6 == i7);//false
        Integer i8 = new Integer(127);
        System.out.println(i5 == i8); //false
        Integer i9 = new Integer(128);
        Integer i10 = new Integer(123);
        System.out.println(i9 == i10);  //false
    }
}


总结
1,无论如何,Integer与new Integer不会相等。不会经历拆箱过程,new出来的对象存放在堆,而非new的Integer常量则在常量池(在方法区),他们的内存地址不一样,所以为false。

2,两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。因为java在编译Integer i2 = 128的时候,被翻译成:Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存。

3,两个都是new出来的,都为false。还是内存地址不一样。

4,int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比。

二、“==”和equals的区别

2.1,什么是==?

==比较运算符,如果进行比较的两个操作数都是
数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true
如果两个操作数都是
引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成==比较的是两个变量的内存地址)

2.2,什么是equals()?

equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.所以,具体的效果还是要看是否进行重写equals()

2.3,区别

所以,从基础类型上来看是返回值,没有什么区别。就看是否进行重写。

2.4,坑

int 和 Integer

public static void main(String[] args) {
        //-128 ~ +127 之间
        Integer a = 5;
        Integer c = new Integer(5);
        System.out.println(a.equals(c)); //ture是因为,在Integer中对equals()进行重写了,返回的就是其中的值,而不是地址了。
        System.out.println(a == c);//自然是flase
}

三、重载与重写的区别

3.1,重写(Override)

从字面上看,重写就是重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。(public>protected>default>private)

public class Father {
    public void sayHello() {
        System.out.println("Hello");
    }
}

class Son extends Father{
    public void sayHello() {
        System.out.println("hello by ");
    }

}

总结:
1.发生在父类与子类之间
2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常(这一条不是很懂)

3.2,重载(Overload)

在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。

public class Father {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Father s = new Father();
        s.sayHello();
        s.sayHello("wintershii");
    }
    public void sayHello() {
        System.out.println("Hello");
    }
    public void sayHello(String name) {
        System.out.println("Hello" + " " + name);
    }
}

重载 总结:
1.重载Overload是一个类中多态性的一种表现
2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
3.重载的时候,**返回值类型可以相同也可以不相同。**无法以返回型别作为重载函数的区分标准

3.3,面试时,问:重载(Overload)和重写(Override)的区别?

答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分

3.4,其中相关问题

class Demo{
int show(int a,int b){return 0;}
}
//下面那些函数可以存在于Demo的子类中。	
public int show(int a,int b){return 0;}//可以,覆盖。	
private int show(int a,int b){return 0;}//不可以,权限不够。
private int show(int a,long b){return 0;}//可以,和父类不是一个函数。没有覆盖,相当于重载。
public short show(int a,int b){return 0;}//不可以,因为该函数不可以和给定函数出现在同一类中,或者子父类中。这个是重点
static int show(int a,int b){return 0;}//不可以,静态只能覆盖静态。

第四个是重点:其不符合重写,因为返回值不同。不符合重载,其方法名,参数列表相同。所以,造成了歧义,所以不符合。

四、子类与父类其中构造函数调用的顺序

子类的构造器是一定要调用父类的构造器吗?

结论:

子类的构造过程中必须调用其父类的构造函数,因为继承关系,子类必须把父类的内容继承下来。但如果父类有多个构造函数时,该如何选择调用呢?
1.子类的构造过程中,必须 调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会默认帮我们加上一个默认的构造方法(就是没有参数的构造方法)如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是**如果在子类构造方法中我们并没有显示的调用基类的构造方法,**如:super();这样就会调用父类没有参数的构造方法。默认调用基类中没有参数的构造方法。

2.如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数,此时无参的构造函数就不会被调用。
在这里插入图片描述
总之,一句话:子类没有显示调用父类构造函数,不管子类构造函数是否带参数都默认调用父类无参的构造函数,若父类没有则编译出错

五、JVM架构和GC垃圾回收机制

在这里插入图片描述
在这里插入图片描述
由于本人才疏学浅,还有些东西还没有看完,剩下的一些知识点待之后研读,在此做个笔记。
JVM架构和GC垃圾回收机制(JVM面试不用愁)
如何啃下JVM这座大山,完结撒花!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值