面试宝典-【JavaSE】

目录

基础语法

1.Java的特点?

2.Java是如何实现跨平台的?

3.JDK/JRE/JVM三者的关系?

4.Java程序是编译执行还是解释执行?

5.说一下Java数据类型?

6.简述 Java 基本数据类型?

7.为什么不能用浮点型表示金额? 

8.自动类型提升和强制类型转换? 

9.为什么需要包装类? 

10.什么是自动拆箱/封箱?

11. & 和 && 的区别?

12.break ,continue ,return 的区别及作用?

13.用最有效率的方法计算 2 乘以 8? 

14.说说自增自减运算?

面向对象

15.面向对象和面向过程的区别?

16.面向对象编程有哪些特性?

17.重载和重写的区别?

18.说一下值传递机制?

19.访问修饰符 public、private、protected、以及不写(默认)时的区别?

20.this 关键字有什么作用? 

21.成员变量与局部变量的区别有哪些?

22.抽象类和接口有什么区别?

23.静态变量和实例变量的区别?

24.final 关键字有什么作用? 

 25.final、finally、finalize 的区别?

26.==和 equals 的区别?

27.super关键字的使用?

28.说一下hashCode 与 equals?

29.为什么两个对象有相同的 hashcode 值,它们也不⼀定相等?

30. Object类的使用?

31.Java 创建对象有哪几种方式?

32.深拷贝与浅拷贝?

33.String 是 Java 基本数据类型吗?可以被继承吗?

34.String 有哪些常用方法?

35.String 和 StringBuilder、StringBuffer 的区别?

36.什么是序列化?什么是反序列化?

37.说说有几种序列化方式?

38.Java 中异常处理体系?

39.异常的处理方式?

40.Java 中 IO 流分为几种?

41.什么是泛型?

42.说一下你对注解的理解?

43.throw和throws的区别?

44.什么是反射?

45.获取Class实例的方式? 

46.反射的原理是什么?

47.JDK1.8 都有哪些新特性?

48.说一下Lambda 表达式?

49.说一下Stream 流用? 


基础语法

1.Java的特点?

  • 1.Java是一门面向对象的编程语言。
  • 2.Java具有平台独立性和移植性。
  • 3.Java 具有较好的安全性和健壮性。Java 提供了异常处理和垃圾回收机制

2.Java是如何实现跨平台的?

  • 1.Java是通过JVM(Java虚拟机)实现跨平台的。 
  • 2.我们编写的Java代码,编译后会生成.class 文件(字节码文件)。
  • 3.Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码,通过JVM翻译成机器码之后才能运行。

3.JDK/JRE/JVM三者的关系?

  • 1.JDK:Java 开发工具包,提供了 Java 的开发环境和运行环境。
  • 2.JRE:Java 运行环境,提供了 Java 运行所需的环境。包含JVM 和 Java 核心类库。
  • 3.JVM:Java 能够跨平台运行的核心在于 JVM,java程序首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。

JRE = JVM + Java 核心类库

JDK = JRE + Java工具 + 编译器 + 调试器

4.Java程序是编译执行还是解释执行?

  • 编译型语言:在程序运行之前,通过编译器将源程序编译成机器码可运行的二进制,以后执行这个程序时,就不用再进行编译了
  • 解释型语言:解释型语言的源代码不是直接翻译成机器码,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。在运行的时候才将源程序翻译成机器码,翻译一句,然后执行一句,直至结束 

对于Java这种语言,它的源代码会先通过javac编译成字节码,再通过jvm将字节码转换成机器码执行,即解释运行和编译运行配合使用,所以可以称为混合型或者半编译型

5.说一下Java数据类型?

java中的变量按照类型分为两种:基本数据类型引用数据类型

  • 1.基本数据类型:
    • 整型:byte、short、int、long
    • 浮点型:float  、double
    • 字符型:char
    • 布尔型:Boolean
  • 2.引用数据类型:
    • 数组
    • 接口
    • 枚举
    • 注解

6.简述 Java 基本数据类型?

  • byte: 占用 1 个字节,取值范围-128 ~ 127
  • short: 占用 2 个字节,取值范围-2^15^ ~ 2^15^-1
  • int:占用 4 个字节,取值范围-2^31^ ~ 2^31^-1
  • long:占用 8 个字节
  • float:占用 4 个字节
  • double:占用 8 个字节
  • char: 占用 2 个字节
  • boolean:占用大小根据实现虚拟机不同有所差异

7.为什么不能用浮点型表示金额? 

  • 计算机中保存的小数是十进制的小数的近似值,并不是准确值,不要在代码中使用浮点数来表示金额等重要的指标。
  • 建议使用BigDecimal

8.自动类型提升和强制类型转换? 

  • 针对于基本数据类型,可以做运算的基本类型有7种,不包含Boolean类型
  • 运算规则:自动类型提升强制类型转换
    • 自动类型提升:当把一个表数范围小的数值直接赋给另一个表数范围大的变量时,可以进行自动类型转换
    • 强制类型转换:如将容量大的变量的类型转换为容量小的变量的类型

9.为什么需要包装类? 

  • 为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各个基本数据类型的变量都提供了对应的包装类。
  • 比如,在集合类中,我们是无法将 int 、double 等类型放进去的。因为集合的容器要求元素是 Object 类型。

  • 原来使用基本数据类型变量的位置,改成包装类以后,对于成员变量来说,其默认值变化了

10.什么是自动拆箱/封箱?

  • 自动装箱:将基础类型转化为包装类型。
  • 自动拆箱:将包装类型转化为基础类型。
Integer a = 10;  //装箱
int n = a;   //拆箱

有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:

  • 赋值操作(装箱或拆箱)
  • 进行加减乘除混合运算 (拆箱)
  • 进行>,<,==比较运算(拆箱)
  • 调用equals进行比较(装箱)
  • ArrayList、HashMap等集合类添加基础类型数据时(装箱)

11. & 和 && 的区别?

  • &&:运算符是短路与运算,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。
  • & :用作位运算符,对整数的二进制表示进行按位与操作。可以与1位运算,判断奇偶性(1:奇数,0偶数)

12.break ,continue ,return 的区别及作用?

  • break 跳出整个循环,不再执行循环(结束当前的循环体)
  • continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
  • return 程序返回不再执行下面的代码(结束当前的方法 直接返回)

13.用最有效率的方法计算 2 乘以 8? 

  • 2 << 3。位运算,数字的二进制位左移三位相当于乘以 2 的三次方。

位运算:

  • <<:每向左一动一位,结果就在原有的基础上 乘2
  • >>:每向右移动一位,结果就在原有的基础上 除2

14.说说自增自减运算?

  • (前)++:先自增一,在运算
  • (后)++:先运算,在自增一
        int a1=10;
        int b1= ++a1;
        //a1=11,b1=11

        int a2=10;
        int b2= a2++;
        //a2=11.b2=10

面向对象

15.面向对象和面向过程的区别?

  • ⾯向过程 :分析出解决问题所需要的步骤,然后用函数按这些步骤实现,使用的时候依次调用就可以了
  • ⾯向对象 :将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

面向过程只用函数实现,面向对象是用类实现各个功能模块。

16.面向对象编程有哪些特性?

面向对象编程有三大特性:封装、继承、多态,(抽象)

  • 封装:将数据(属性,或者叫字段)和操作数据的方法(行为)捆绑在一起,形成一个独立的对象(类的实例)。
  • 继承:继承允许一个类(子类)继承现有类(父类或者基类)的属性和方法。Java中是单继承的,也就是说一个子类只有一个父类。
  • 多态:多态是同一个行为具有多个不同表现形式的能力。实现多态的三要素:继承、重写、父类引用指向子类对象
    • 好处:
      • 了提高代码的灵活性和可扩展性,使得代码更容易维护和扩展
  • 抽象:把客观事物用代码抽象出来。

17.重载和重写的区别?

  • 重载:在同一个类中,允许存在一个以上的同名方法,它们的参数列表不同
    •  两同一不同:同一个类,相同的方法名,不同的参数列表(参数个数,参数类型)
    • 注意:方法的重载与形参的名、权限修饰符、返回值类型都没有关系。
  • 重写方法的重写描述的是父类和子类之间的,当父类的功能无法满足子类的需求,可以在子类对方法进行重写。
    • 子类重写方法的方法名和形参列表与父类中被重写方法的方法名和形参列表相同
    • 子类重写的方法的权限修饰符不小于父类中被重写方法的权限修饰符;
    • 子类不能重写父类中声明为private权限方法
    • 子类重写方法抛出的异常类型不大于父类被重写方法抛出的异常类型
    • 返回值类型:
      • 父类被重写方法返回值类型void,则子类重写方法的返回值类型也是void
      • 父类被重写方法返回值类型A类型,则子类重写的方法返回值类型A类或者A类的子类
      • 父类被重写方法返回值类型如果是基本数据类型,则子类重写的方法返回值类型必须是相同的基本数据类型
    • 注意:子类和父类中的同名同参数方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)

18.说一下值传递机制?

  • 如果是基本数据类型的变量,则将此变量保存的数据值传递出去。
  • 如果是引用数据类型的变量,则将此变量保存的地址值传递出去。

19.访问修饰符 public、private、protected、以及不写(默认)时的区别?

四种权限修饰符:private 、default、protected、public

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。可以修饰在类、接口、变量、方法。
  • private : 在同一类内可见。可以修饰变量、方法。注意:不能修饰类(外部类)
  • public : 对所有类可见。可以修饰类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。可以修饰变量、方法。注意:不能修饰类(外部类)

20.this 关键字有什么作用? 

  • this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针
  • this 的用法在 Java 中大体可以分为 3 种:
    • 1.普通的直接引用,this 相当于是指向当前对象本身
    • 2.形参与成员变量名字重名,用 this 来区分:
    • 3.引用本类的构造函数

21.成员变量与局部变量的区别有哪些?

  • 按照数据类型来分:基本数据类型引用数据类型
  • 按照变量在类中声明的位置的不同:成员变量(或属性)、局部变量
  • 相同点:
    • 变量声明的格式相同:数据类型 变量名 = 变量值。
    • 变量都有其有效的作用域。
    • 变量必须先声明,后赋值,再使用。
  • 不同点:
    • 类中声明的位置的不同
      • 成员变量是属于类的
      • 局部变量是在⽅法中定义的变量或是⽅法的参数。
    • 在内存中分配的位置不同
      • 成员变量随着对象的创建,存储在堆空间中;
      • 局部变量:存储在栈空间中
      • 如果成员变量是使⽤ static 修饰的,那么这个成员变量是属于类的,如果没有使⽤ static 修饰,这个成员变量是属于实例的。
    • 生命周期
      • 成员变量随着对象的创建而创建,随着对象的消亡而消亡
      • 局部变量随着⽅法的调⽤⽽⾃动消失。
    • 是否可以有权限修饰符进行修饰:
      • 成员变量是可以使用权限修饰符进行修饰的。
      • 局部变量,不能使用任何权限修饰符进行修饰的。
    • 是否有默认值
      • 成员变量都有默认初始化值
      • 局部变量:都没有默认初始化值。

22.抽象类和接口有什么区别?

 一个类只能继承一个类;但一个类可以实现多个接口。

  • 抽象类:
    • 1.被abstract关键字修饰的类叫做抽象类,抽象方法只有方法的声明,没有方法体
    • 2.抽象类不能被实例化。
    • 3.抽象类只能被继承,抽象类的子类必须重写父类的抽象方法,并提供方法体。
    • 4.抽象类中一定有构造器,便于子类实例化时调用
    • 抽象类中可以没有抽象方法。抽象方法所在的类,一定是抽象类。
  • 接口:
    • 接口中不能定义构造器,说明不能实例化;
    • 接口采用多继承机制。
    • 接口中的所有成员变量都默认是由public static final修饰的。
    • 接口中的所有抽象方法都默认是由public abstract修饰的。

23.静态变量和实例变量的区别?

  • 成员变量:按照是否使用static修饰进行分类:
    • 使用static修饰的成员变量:静态变量、类变量
    • 不使用static修饰的成员变量:非静态变量、实例变量
  • 1.实例变量:必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。。
  • 2.静态变量:是被 static 修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个副本。
  • 不同点:
    • 个数
      • 静态变量:在内存空间中只有一份,被类的多个对象所共享。
      • 实例变量:类的每一个实例(或对象)都保存着一份实例变量。
    • 内存位置
      • 静态变量: jdk6及之前:存放在方法区。jdk7及之后:存放在堆空间>
      • 实例变量:存放在堆空间的对象实体中。
    • 加载时机
      • 静态变量:随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份。
      • 实例变量:随着对象的创建而加载。每个对象拥有一份实例变量。
    • 调用者
      • 静态变量:可以被类直接调用,也可以使用对象调用。
      • 实例变量:只能使用对象进行调用。
    • 消亡实际
      • 静态变量:随着类的卸载而消亡
      • 实例变量:随着对象的消亡而消亡

24.final 关键字有什么作用? 

  • 1.final可以用来修饰的结构:类、方法、变量
  • 2.final修饰类:表示此类不能被继承。
  • 3.final 修饰方法:表示这个方法不能被重写。
  • 4.final 修饰变量时:表示这个变量的值一旦被初始化就不能被修改。
    • 如果是基本数据类型的变量,其数值一旦在初始化之后就不能更改;
    • 如果是引用类型的变量,在对其初始化之后就不能再让其指向另一个对象,但是引用指向的对象内容可以改变。

 25.final、finally、finalize 的区别?

  • 1.final 是一个修饰符口,可以修饰类、方法和变量。
  • 2.finally 是 Java 中异常处理的一部分,用来创建 try 块后面的 finally 块。无论 try 块中的代码是否抛出异常,finally 块中的代码总是会被执行。
  • 3.finalize 是Object 类的一个方法,用于在垃圾回收器将对象从内存中清除出去之前做一些必要的清理工作。

26.==和 equals 的区别?

  • ==:用于基本数据类型引用数据类型的比较
    • 当进行基本数据类型比较时,比较值是否一致
    • 当进行引用数据类型比较时,比价的是栈内存中地址是否一致
  • equals只能进行引用数据类型比较
    •  当没有重写equals方法时,比较的是栈内存地址是否一致
    • 当重写equals方法时,比较堆内存中存储的数据值是否一致

27.super关键字的使用?

  • super可以调用的结构:属性、方法、构造器 
  • super调用父类的属性、方法:
    • 如果子父类中出现了同名的属性,此时使用super.的方式,表明调用的是父类中声明的属性。
    • 子类重写了父类的方法。如果子类的任何一个方法中需要调用父类被重写的方法时,需要使用super
  • super调用构造器:
    • 在子类的构造器中,首行要么使用了"this(形参列表)",要么使用了"super(形参列表)"。

28.说一下hashCode 与 equals?

  • 1.hashCode() 方法返回该对象的哈希码值。这个值通常用于哈希表数据结构,例如 HashMap,以确定对象在哈希表中的存储位置。
  • 如果两个对象根据 equals(Object) 方法是相等的,那么调用这两个对象中任一对象的 hashCode 方法必须产生相同的整数结果。
  • 如果重写了 equals()方法而没有重写 hashCode()方法,那么被认为相等的对象可能会有不同的哈希码,从而导致无法在集合中正确处理这些对象。

29.为什么两个对象有相同的 hashcode 值,它们也不⼀定相等?

  1. 如果两个对象调用equals比较返回true,那么它们的hashCode值一定要相同;
  2. 如果两个对象的hashCode相同,它们并不一定相同。

30. Object类的使用?

  • 任何一个Java类(除Object类)都直接或间接的继承于Object类
  • Object声明的方法:
    • 对象比较
      • public native int hashCode():相等的对象必须具有相等的哈希码。如果重写了 equals 方法,就应该重写 hashCode 方法。
      • public boolean equals(Object obj):用于比较 2 个对象的内存地址是否相等
    • 对象拷贝

      • protected native Object clone() throws CloneNotSupportedException:返回此对象的一个副本,默认实现只做浅拷贝口,且类必须实现 Cloneable 接口。
    • 对象转字符串

      • public String toString():返回对象的字符串表示
    • 线程调度

      • public final native void notify():唤醒在此对象监视器上等待的单个线程。如果有多个线程等待,选择一个线程被唤醒。
      • public final native void notifyAll():唤醒在此对象监视器上等待的所有线程。
      • public final void wait() throws InterruptedException :调用该方法会导致当前线程等待,直到另一个线程调用此对象的 notify()方法或 notifyAll()方法。
      • public final native void wait(long timeout) throwsInterruptedException:等待timeout毫秒,如果在timeout毫秒内没有被唤醒,会自动唤醒。
      • public final void wait(long timeout, int nanos) throwsInterruptedException:更加精确了,等待 timeout 毫秒和 nanos 纳秒,如果在 timeout 毫秒和 nanos 纳秒内没有被唤醒,会自动唤醒
    • 垃圾回收:
      • protected void finalize() throws Throwable :当垃圾回收器决定回收对象占用的内存时调用此方法,用于清理资源
    • 反射:
      • public final native Class<?> getClass():用于获取对象的类信息,如类名。

31.Java 创建对象有哪几种方式?

  • new 创建新对象
  • 通过反射机制
  • 采用 clone 机制
  • 通过序列化机制

32.深拷贝与浅拷贝?

  • 浅拷贝:仅拷贝被拷贝对象的成员变量的值,也就是基本数据类型变量的值,和引用数据类型变量的地址值,而对于引用类型变量指向的堆中的对象不会拷贝。
  • 深拷贝:完全拷贝一个对象,拷贝被拷贝对象的成员变量的值,堆中的对象也会拷贝一份。
  • 实现浅拷贝:Object 类提供的 clone()方法可以非常简单地实现对象的浅拷贝。
  • 实现深拷贝:
    • 重写克隆方法:重写克隆方法,引用类型变量单独克隆
    • 序列化:可以先将原对象序列化,再反序列化成拷贝对象。

33.String 是 Java 基本数据类型吗?可以被继承吗?

  • 不是,String 是一个类,属于引用数据类型。
  • String 类使用 final 修饰,是所谓的不可变类,无法被继承。 

34.String 有哪些常用方法?

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引处的字符。
  • replace():字符串替换。
  • trim():去除字符串两端空白。
  • split():分割字符串,返回一个分割后的字符串数组。
  • getBytes():返回字符串的 byte 类型数组。
  • length():返回字符串长度。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较。

35.String 和 StringBuilder、StringBuffer 的区别?

  • String:不可变的字符序列,因此也是线程安全的,每次对String对象进行修改操作(如拼接、替换等)实际上都会生成一个新的String对象 ,底层使用byte[](jdk9之后)
  • StringBuffer:可变的字符序列,是线程安全的,内部使用 synchronized 进行同步,底层使用char[](jdk8之前);底层使用byte[](jdk9之后)
  • StringBuilder:可变的字符序列,不是线程安全的,底层使用char[](jdk8之前);底层使用byte[](jdk9之后)

36.什么是序列化?什么是反序列化?

  • 序列化:把 Java 对象转为二进制流,方便存储和传输。 
  • 反序列化:把二进制流恢复成对象。

  • Serializable 接口:这个接口只是一个标记,没有具体的作用,但是如果不实现这个接口,在有些序列化场景会报错,所以一般建议,创建的 JavaBean 类都实现 Serializable。
  • serialVersionUID :起验证作用。
private static final long serialVersionUID = 1L;

这个 ID 其实就是用来验证序列化的对象和反序列化对应的对象 ID 是否一致。

37.说说有几种序列化方式?

  • Java 对象序列化 :Java 原生序列化方法即通过 Java 原生流(InputStream 和 OutputStream 之间的转化)的方式进行转化,一般是对象输出流 ObjectOutputStream和对象输入流
  • json 序列化:这个可能是我们最常用的序列化方式,Json 序列化的选择很多,一般会使用 jackson 包,通过 ObjectMapper 类来进行一些操作,比如将对象转化为 byte 数组或者将 json 串转化为对象。
  • ProtoBuff 序列化:ProtocolBuffer 是一种轻便高效的结构化数据存储格式,ProtoBuff 序列化对象可以很大程度上将其压缩,可以大大减少数据传输大小,提高系统性能

38.Java 中异常处理体系?

  • Throwable 是 Java 语言中所有错误和异常的基类,包括Error 和 Exception;
  • Error: Java虚拟机无法解决的严重问题。例如:StackOverflowErrdn (栈内存溢出)和OutofMemoryError (堆内存溢出,简称OOM)
  • Exception 类代表程序可以处理的异常。
  • 它分为两大类:编译时异常(Checked Exception)和运行时异常(Runtime Exception)。
    • 编译时异常(Checked Exception):这类异常在编译时必须被显式处理(捕获或声明抛出)。
    • 行时异常(Runtime Exception):这类异常在运行时抛出,它们都是 RuntimeException 的子类

39.异常的处理方式?

  • 处理异常的方式:捕获异常和抛出异常
    • 抛出异常:抛出异常有两种形式一是 throw,一个 throws
    • 捕获异常:利用try catch 捕获异常
       try {
            //包含可能会出现异常的代码以及声明异常的方法
        }catch(Exception e) {
            //捕获异常并进行处理
        }finally {                                                       }
            //可选,必执行的代码
        }

finally 语句块不管程序是否正常执行,最终它都会必然执行

40.Java 中 IO 流分为几种?

  • 按照数据流方向
    • 输入流(Input Stream):从源(如文件、网络等)读取数据到程序
    • 输出流(Output Stream):将数据从程序写出到目的地(如文件、网络、控制台等)。
  • 按处理数据单位:

    • 字节流(Byte Streams):以字节为单位读写数据,主要用于处理二进制数据,如音频、图像文件等。

    • 字符流(Character Streams):以字符为单位读写数据,主要用于处理文本数据。
  • 按功能:

    • 节点流(Node Streams):直接与数据源或目的地相连,如 FileInputStream、FileOutputStream。
    • 处理流(Processing Streams):对一个已存在的流进行包装,如缓冲流 BufferedInputStream、BufferedOutputStream。
    • 管道流(Piped Streams):用于线程之间的数据传输,如 PipedInputStream、PipedOutputStream。

41.什么是泛型?

  • 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 
  • 泛型一般有三种使用方式:泛型类泛型接口泛型方法

42.说一下你对注解的理解?

  • Java 注解本质上是一个标记。 
  • 注解的本质是一个接口,这个接口继承自java.lang.annotation.Annotation接口
  • 注解可以标记在类上、方法上、属性上等 

43.throw和throws的区别?

  • throw:用于抛出一个具体的异常对象。

  • throws:用在方法签名中,用于声明该方法可能抛出的异常。子类方法抛出的异常范围更加小,或者根本不抛异常

44.什么是反射?

  •  动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

45.获取Class实例的方式? 

  • 1.类.class
  • 2.对象.getClass
  • 3.Class.forName(类的全类路径名)
  • 4.使用类加载器
        //1.类.class
        Class userClass1 = User.class;

        //2.对象.getClass
        User user = new User();
        Class userClass2 = user.getClass();

        //3.Class.forName(类的全类路径名)
        Class userClass3 = Class.forName("com.mytest.User");

        //4.使用类的加载器
        Class userClass4 = ClassLoader.getSystemClassLoader().loadClass("com.mytest.User");

46.反射的原理是什么?

  •  Java 程序的执行分为编译和运行两步,编译之后会生成字节码(.class)文件,JVM 进行类加载的时候,会加载字节码文件,将类型相关的所有信息加载进方法区,反射就是去获取这些信息,然后进行各种操作。 

47.JDK1.8 都有哪些新特性?

  • 1.接口默认方法 :Java 8 允许我们给接口添加一个非抽象的方法实现,只需要使用 default 关键字修饰即可
  • 2.Stream API:用函数式编程方式在集合类上进行复杂操作的工具,配合 Lambda 表达式可以方便的对集合进行处理。
  • 3.日期时间 API:Java 8 引入了新的日期时间 API 改进了日期时间的管理。
  • 4.Optional 类:用来解决空指针异常的问题。
  • 5.Lambda 表达式和函数式接口:Lambda允许把函数作为一个方法的参数

48.说一下Lambda 表达式?

  • Lambda 表达式本质上是一段匿名内部类,也可以是一段可以传递的代码。
  • ->的左边: lambda形参列表,对应着要重写的接口中的抽象方法的形参列表。
  • ->的右边: lambda体,对应着接口的实现类要重写的方法的方法体。
        Runnable r1 = new Thread() {
            @Override
            public void run() {
                System.out.println("hello 小张");
            }
        };
        r1.run();

        //lambda
        Runnable r2 = () -> {
            System.out.println("hello 小张");
        };
        r2.run();

49.说一下Stream 流用? 

Stream 流一般用于集合,我们对一个集合做几个常见操作:

 List<Integer> list=new ArrayList<>();
        list.add(100);
        list.add(300);
        list.add(900);
        list.add(500);
        list.add(700);
        
  • Filter 过滤:
        //过滤出数字大于500的,并打印
        list.stream().filter((num) -> num > 500).forEach(System.out::println);
  • sorted排序:
        //过滤出数字大于100的,并排序打印
        list.stream().sorted().filter((num)->num>100).forEach(System.out::println);
  • Map 转换
  list.stream().map((num)->num+1).forEach((System.out::println));
  • distinct去重:
        //去重
        list.stream().distinct().forEach((System.out::println));
  • skip跳过:
        //从第一个元素开始打印
        list.stream().skip(2).forEach((System.out::println));
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会敲代码的小张

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

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

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

打赏作者

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

抵扣说明:

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

余额充值