一定要会的Java基础问题

Java基础

一、Java中的8种基本数据类型

java中有哪些基本类型,它们的默认值和占用空间大小,对应的包装类型。

基本类型包装器类型位数字节(重要)默认值
intInteger3240
shortShort1620
longLong6480L
byteByte810
charCharacter162'u0000'
floatFloat3240f
doubleDouble6480d
booleanBoolean1 false

对于boolean,官方未明确的定义,它依赖于JVM厂商的具体实现,逻辑上理解为占用1位,实际考虑计算机高效存储因素。
Java中,使用long类型的数据一定要在后面加上L,否则将被作为整型解析。
char:单引号 ,String:双引号

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

包装类型不赋值就是Null,而基本类型有默认值且不是Null。
从JVM层面讲,基本数据类型直接存放在Java虚拟机栈中的局部变量表中,而包装类型属于对象类型,对象类型都存在与堆中,相比对象类型,基础类型占用的空间要小很多。

二、包装类型的常量池技术

Java基本类型的包装类的大部分都使用了常量池技术,ByteShortIntegerLong 这4种包装类默认创建数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值 [0,127] 范围的缓存数据,
在范围区间内的值可以直接使用==进行判断,是因为缓存数据会复用已有的对象,但是区间外的数据都会在堆上产生,并不会复用对象,而是创建一个新的对象,所以推荐使用equals方法进行判断。
Boolean 直接返回 True or False

所有包装类对象之间值的比较,全部使用equals方法比较。

三、为什么要有包装类型

Java本身就是面向对象的语言,对象是Java的灵魂,除了定义一些局部变量以外,但是在方法参数、对象属性中很少使用基本类型定义。
假如一个对象的属性用了基本类型,那这个属性就存在默认值,这个逻辑不正确,很多场景下,对象的某些属性没有赋值,希望为null。
另外,泛型参数不可以是基本类型,基本类型不是Object类,应该用其对应的包装类。
Java中的集合定义的时候不能使用基本类型。

四、自动拆箱装箱

装箱:将基本类型用包装器包装起来,装箱就是调用了包装类的valueOf() 方法。
拆箱:将包装器类型转换为基本类型,拆箱就是调用了xxxValue() 方法。

Integer i = 10 等于 Integer i = Integer.valueOf(10)
int n = i 等于 int n = i.intValue();

五、自动拆箱引起的NPE问题

数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险。
三目运算符使用不当会导致诡异的NPE现象。

六、String、StringBuffer和StringBuilder的区别,为什么String是不可变的

在Java8中,String内部使用了char数组存储数据,并被声明为final ,因此它不可以被继承。

String设计成不可变的好处:

  1. 可以缓存Hash值
    因为String的hash值经常被使用,例如String用作HashMap的Key。不可变的特性使得hash值也不可变,因此只需要进行一次计算。
  2. 常量池优化
    String对象创建后,会在字符串常量池进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。
  3. 线程安全
    String不可变性具备线程安全,可以在多个线程中安全使用。

String、StringBuffer和StringBuilder的区别:

  • 可变性
    String不可变,StringBuffer和StringBuilder是可变的。
  • 线程安全性
    String是不可变的,所以是线程安全,StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全,StringBuilder并没有对方法加同步锁,所以不是线程安全。
  • 性能
    StringBuilder > StringBuffer > String

七、重载和重写的区别

  • 重载:重载发生在同一个类中,方法名相同参数列表不同(参数列表类型不同,顺序不同,大小不同),与方法返回值和访问修饰符无关,重载的方法不能根据返回值类型进行区分。
  • 重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类;如果父类方法用private 则子类中的就不是重写。

八、==和equals()的区别

  • ==对于基本类型,==是比较值;对于引用类型,==比较的是内存地址。
  • equals()有两种情况:
    类没有重写equals()方法,通过equals()比较两个对象,等价于==比较这两个对象,默认使用Object类equals()方法。
    类重写了equals()方法,通过equals()比较两个的对象的属性是否相等,相等返回true。

九、Java反射,反射的优缺点,解决的问题

Java反射

Java反射机制是在运行状态中,对于任意一个类,都能知道它的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为反射
反射获取对象的三种方式:
对象.getClass();
类.Class;
Class.forName();

优缺点:

  • 优点:运行期类型的判断,动态加载类,提高了代码的灵活度。
  • 缺点:性能比直接的Java代码要慢很多。

解决的问题(应用场景)

  • Java的很多框架都用到了反射,例如Spring种的xml配置模式。
  • 动态代理设计模式也采用了反射机制。

十、Java泛型,泛型的作用,什么是类型擦除,泛型有哪些限制

Java泛型

Java泛型是JDK5引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说操作的数据类型被指定为一个参数。

泛型的作用

为了解决Java容器无法记忆元素类型的问题。

类型擦除

Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。
Java编译器是通过先检查代码中泛型的类型,然后在进行类型擦除,再进行编译。

泛型有哪些限制

Java泛型不能使用基本类型
Java泛型不允许进行实例化
Java泛型不允许进行静态化
Java泛型不允许直接进行类型转换(通配符可以)
Java泛型不允许直接使用instanceof运算符进行运行时类型检查(通配符可以)
Java泛型不允许创建确切类型的泛型数组(通配符可以)
Java泛型不允许定义泛型异常类或者catch异常(throws可以)
Java泛型不允许作为参数进行重载

十一、内部类

内部类包含:成员内部类、局部内部类、匿名内部类和静态内部类。

  • 成员内部类

    1. 成员内部类定义为位于另一个类的内部,成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

    2. 当成员内部类拥有和外部类同名的成员变量或者方法时,即默认情况下访问的是成员内部类的成
      员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类. this .成员变量

    3. 在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个
      对象的引用来访问。

    4. 成员内部类是依附外部类而存在的,如果要创建成员内部类的对象,前提是必须存在一个外部类 的对象。

  • 局部内部类
    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。

  • 匿名内部类
    匿名内部类只没有名字的内部类,在日常开发中使用较多。使用匿名内部类的前提条件:必须继承一个父类或实现一个接口。

  • 静态内部类
    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static 。静态内部类是不需要依赖于外部类的,并且它不能使用外部类的非static 成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static 成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

  • 内部类的优点:

    1. 内部类不为同一包的其他类所见,具有很好的封装性;
    2. 匿名内部类可以很方便的定义回调。
    3. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实
      现,对于内部类都没有影响。
    4. 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。

十二、BIO、NIO、AIO区别

  • BIO (Blocking I/O):服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制来改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务端资源要求比较高,并发局限于应用中,在jdk1.4以前是唯一的io。

  • NIO (New I/O):服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,jdk1,4开始支持。

  • AIO (Asynchronous I/O):服务器实现模式为一个有效请求一个线程,客户端的IO请求都是由操作系统先完成了再通知服务器用其启动线程进行处理。AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,jdk1.7开始支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

As_theWind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值