JAVA面试必备--JAVA基础篇(二)之 基础常识

      相信很多同行小伙伴会因为许多原因想跳槽,不论是干得不开心还是想跳槽涨薪,在如此内卷的行业,我们都面临着“面试造火箭,上班拧螺丝”的局面,鉴于当前形势博主呕心沥血整理的干货满满的造火箭的技巧来了,本博主花费2个月时间,整理归纳java全生态知识体系常见面试题!总字数高达百万! 干货满满,每天更新,关注我,不迷路,用强大的归纳总结,全新全细致的讲解来留住各位猿友的关注,希望能够帮助各位猿友在应付面试笔试上!当然如有归纳总结错误之处请各位指出修正!如有侵权请联系博主QQ1062141499! 

目录

1 Java属于编译型还是解释型语言?

2 如何让计算机最高效的算出2乘以8?

3 javap的作用是什么?

4 Math.round(15)等于多少? Math.round(- 15) 又等于多少

5 静态与非静态成员变量区别?

6 静态变量和实例变量的区别

7  File的常用方法都有哪些?

8 nio中的Files类常用方法有哪些?

9  为什么要使用克隆

10 如何实现对象克隆

11 深拷贝和浅拷贝区别是什么

12 如何跳出当前的多重嵌套循环

13 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

14 不通过构造方法能创建对象吗?

15 静态方法内部能对非静态调用吗?

16 Object有哪些公用方法

17 static class与non static class的区别

18 什么是xml

19 xml解析的两种基本方式:DOM和SAX的区别是?

20 Java中有哪些解析XML的类库?有什么特点?

21 XML文档定义分为 Schema 和 DTD 两种形式

22 Java1.7与1.8,1.9,10 新特性

23 JDK8中Stream接口的常用方法

24 JNI的使用

25 什么是JAVA内部类?

  25.1、概念

  25.2、分类

        25.3、内部类的作用

          25.4、特点

26 匿名内部类可以继承类或实现接口吗?为什么?

27 内部类可以引用它的外部类的成员吗?有什么限制?

28 java如何实现其他语言的高阶函数


   

1 Java属于编译型还是解释型语言?

       计算机不能直接理解高级语言,只能理解和运行机器语言。必须要把高级语言翻译成机器语言,计算机才能运行高级语言所编写的程序。

       翻译的方式有两种,一个是编译,一个是解释

       用编译型语言写的程序执行之前,需要一个专门的编译过程,通过编译系统把高级语言翻译成机器语言,把源高级程序编译成为机器语言文件,以后直接运行而不需要再编译了,所以一般编译型语言的程序执行效率高。

      解释型语言在运行的时候才解释成机器语言,每个语句都是执行时才翻译。每执行一次就要翻译一次,效率较低。

       Java 是一种兼具编译和解释特性的语言,.java 文件会被编译成与平台无关的 .class 文件,但是 .class 字节码文件无法被计算机直接,仍然需要 JVM 进行翻译成机器语言。

       所以严格意义上来说,Java 是一种解释型语言

总结

      个人认为,java是解释型的语言,因为虽然java也需要编译,编译成.class文件,但是并不是机器可以识别的语言,而是字节码,最终还是需要 jvm的解释,才能在各个平台执行,这同时也是java跨平台的原因。所以可是说java即是编译型的,也是解释型,但是假如非要归类的话,从概念上的定义,恐怕java应该归到解释型的语言中。

      编译型的语言包括:C、C++、Delphi、Pascal、Fortran

      解释型的语言包括:Java、Basic、javascript、python

2 如何让计算机最高效的算出2乘以8?

       2 <<3

       位运算符 <<,是将一个数左移 n 位,相当于乘以了 2 的 n 次方

        一个数乘以 8 只要将其左移 3 位即可

        CPU 直接支持位运算,效率最高

        补充:当这个数接近Java基本整数类型的最大值时,左移位运算可能出现溢出,得出负值。

3 javap的作用是什么?

      javap 是 Java class文件分解器,可以反编译,也可以查看 java 编译器生成的字节码等。

javap 命令参数

javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
  -help  --help  -?        输出此用法消息
  -version                 版本信息
  -v  -verbose             输出附加信息
  -l                       输出行号和本地变量表
  -public                  仅显示公共类和成员
  -protected               显示受保护的/公共类和成员
  -package                 显示程序包/受保护的/公共类
                           和成员 (默认)
  -p  -private             显示所有类和成员
  -c                       对代码进行反汇编
  -s                       输出内部类型签名
  -sysinfo                 显示正在处理的类的
                           系统信息 (路径, 大小, 日期, MD5 散列)
  -constants               显示静态最终常量
  -classpath <path>        指定查找用户类文件的位置
  -bootclasspath <path>    覆盖引导类文件的位置

测试类:

public class Testsynchronized {
    public void sync() {
        synchronized (this) {
            System.out.println("sync");
        }
    }
}

使用命令进行反汇编    javap -c Testsynchronized

警告: 二进制文件Testsynchronized包含Lee.interview.Testsynchronized
Compiled from "Testsynchronized.java"
public class Lee.interview.Testsynchronized {
  public Lee.interview.Testsynchronized();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return
  public void sync();
    Code:
       0: aload_0
       1: dup
       2: astore_1
       3: monitorenter
       4: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;
       7: ldc           #21                 // String sync
       9: invokevirtual #22                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      12: aload_1
      13: monitorexit
      14: goto          20
      17: aload_1
      18: monitorexit
      19: athrow
      20: return
    Exception table:
       from    to  target type
           4    14    17   any
          17    19    17   any
}

4 Math.round(15)等于多少? Math.round(- 15) 又等于多少

      Math.round(11.5)的返回值是  12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行取整。

5 静态与非静态成员变量区别?

      生命周期不同:非静态成员变量随着对象的创建而存在;静态成员变量随着类的加载而存在

      调用方式不同:非静态成员变量用 对象名.变量名 调用;静态成员变量用 类名.变量名,JDK1.7以后也能用对象名.变量名调用

      别名不同:非静态成员变量也称为实例变量;静态变量称为类变量

      数据存储位置不同:成员变量数据存储在堆内存的对象中,对象的特有数据;静态变量数据存储在方法区(共享数据区)的静态区,对象的共享数据

6 静态变量和实例变量的区别

       静态变量:是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;

       实例变量:必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

7  File的常用方法都有哪些?

•       Files. exists():检测文件路径是否存在。

•       Files. createFile():创建文件。

•       Files. createDirectory():创建文件夹。

•       Files. delete():删除一个文件或目录。

•       Files. copy():复制文件。

•       Files. move():移动文件。

•       Files. size():查看文件个数。

•       Files. read():读取文件。

•       Files. write():写入文件。

8 nio中的Files类常用方法有哪些?

  • isExecutable:文件是否可以执行
  • isSameFile:是否同一个文件或目录
  • isReadable:是否可读
  • isDirectory:是否为目录
  • isHidden:是否隐藏
  • isWritable:是否可写
  • isRegularFile:是否为普通文件
  • getPosixFilePermissions:获取POSIX文件权限,windows系统调用此方法会报错
  • setPosixFilePermissions:设置POSIX文件权限
  • getOwner:获取文件所属人
  • setOwner:设置文件所属人
  • createFile:创建文件
  • newInputStream:打开新的输入流
  • newOutputStream:打开新的输出流
  • createDirectory:创建目录,当父目录不存在会报错
  • createDirectories:创建目录,当父目录不存在会自动创建
  • createTempFile:创建临时文件
  • newBufferedReader:打开或创建一个带缓存的字符输入流
  • probeContentType:探测文件的内容类型
  • list:目录中的文件、文件夹列表
  • find:查找文件
  • size:文件字节数
  • copy:文件复制
  • lines:读出文件中的所有行
  • move:移动文件位置
  • exists:文件是否存在
  • walk:遍历所有目录和文件
  • write:向一个文件写入字节
  • delete:删除文件
  • getFileStore:返回文件存储区
  • newByteChannel:打开或创建文件,返回一个字节通道来访问文件
  • readAllLines:从一个文件读取所有行字符串
  • setAttribute:设置文件属性的值
  • getAttribute:获取文件属性的值
  • newBufferedWriter:打开或创建一个带缓存的字符输出流
  • readAllBytes:从一个文件中读取所有字节
  • createTempDirectory:在特殊的目录中创建临时目录
  • deleteIfExists:如果文件存在删除文件
  • notExists:判断文件不存在
  • getLastModifiedTime:获取文件最后修改时间属性
  • setLastModifiedTime:更新文件最后修改时间属性
  • newDirectoryStream:打开目录,返回可迭代该目录下的目录流
  • walkFileTree:遍历文件树,可用来递归删除文件等操作

 如测试获取文件所属人

public static void testGetOwner() throws IOException {
	Path path_js = Paths.get("/Users/Lee/Desktop/index.js");
	System.out.println(Files.getOwner(path_js));
}

9  为什么要使用克隆

克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。

10 如何实现对象克隆

•       实现 Cloneable 接口并重写 Object 类中的 clone() 方法。

•       实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

11 深拷贝和浅拷贝区别是什么

   浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。

     深拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。

public static void testGetOwner() throws IOExc

12 如何跳出当前的多重嵌套循环

     在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用)。

13 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

      是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和  C#中可以通过传引用或传输出参数来改变传入的参数的值。说明:Java 中没有传引用实在是非常的不方便,这一点在  Java 8  中仍然没有得到改进,正是如此在  Java 编写的代码中才会出现大量的  Wrapper  类(将需要通过方法调用修改的引用置于一个  Wrapper 类中,再将  Wrapper 对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从  C 和  C++转型为  Java 程序员的开发者无法容忍。

14 不通过构造方法能创建对象吗?

Java 创建对象的方式

  1. 用 new 语句创建对象
  2. 运用反射,调用 java.lang.Class 或 java.lang.reflect.Constructor类的newInstance()方法
  3. 调用对象的 clone() 方法
  4. 运用反序列化手段,调用 java.io.ObjectInputStream 对象的 readObject() 方法

     1、2 会调用构造函数

     3、4 不会调用构造函数

15 静态方法内部能对非静态调用吗?

     不能

  1. 静态方法只能访问静态成员
  2. 调用静态方法时可能对象并没有被初始化,此时非静态变量还未初始化
  3. 非静态方法的调用和非静态成员变量的访问要先创建对象

16 Object有哪些公用方法

     Object是所有类的父类,任何类都默认继承Object

      clone 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。

      equals 在Object中与==是一样的,子类一般需要重写该方法。

      hashCode 该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。

      getClass final方法,获得运行时类型

      wait 使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。 wait() 方法一直等待,直到获得锁或者被中断。 wait(long timeout) 设定一个超时间隔,如果在规定时间内没有获得锁就返回。

 调用该方法后当前线程进入睡眠状态,直到以下事件发生

       1、其他线程调用了该对象的notify方法。

       2、其他线程调用了该对象的notifyAll方法。

       3、其他线程调用了interrupt中断该线程。

       4、时间间隔到了。

      5、此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。

      notify 唤醒在该对象上等待的某个线程。

      notifyAll 唤醒在该对象上等待的所有线程。

       toString 转换成字符串,一般子类都有重写,否则打印内存地址。

17 static class与non static class的区别

      static class(内部静态类)

             1、用static修饰的是内部类,此时这个内部类变为静态内部类;对测试有用。

             2、内部静态类不需要有指向外部类的引用。

             3、静态类只能访问外部类的静态成员,不能访问外部类的非静态成员。

        non static class(非静态内部类)

              1、非静态内部类需要持有对外部类的引用。

              2、非静态内部类能够访问外部类的静态和非静态成员。

              3、一个非静态内部类不能脱离外部类实体被创建。

              4、一个非静态内部类可以访问外部类的数据和方法。

package com.junli.java.innerClass;
/**
 * 内部类测试
 */
public class InnerClassDemo {
    public static void main(String[] args) {
        //访问非静态内部类
        Outer.Inner inner = new Outer().new Inner();
        System.out.println(inner.name);
        //访问静态内部类
        Outer.StaticInner staticInner = new Outer.StaticInner();
        System.out.println(staticInner.name);
        //访问非静态内部类的非静态内部类
        Outer.Inner.InnerInner innerInnerClass =
                new Outer().new Inner().new InnerInner();
        System.out.println(innerInnerClass.name);
    }
}
class Outer {
    class Inner {
        String name = "Inner";
        class InnerInner {
            String name = "InnerInner";
        }
    }
    static class StaticInner {
        String name = "StaticInner";
    }
}

18 什么是xml

     xml是一种可扩展性标记语言,支持自定义标签(使用前必须预定义)使用DTD和XMLSchema标准化XML结构。

      优点:用于配置文件,格式统一,符合标准;用于在互不兼容的系统间交互数据,共享数据方便;

       缺点:xml文件格式复杂,数据传输占流量,服务端和客户端解析xml文件占用大量资源且不易维护

19 xml解析的两种基本方式:DOM和SAX的区别是?

        DOM: document object model

         SAX: simple api for xml

       DOM一次性把xml文件全部加载到内存中简历一个结构一摸一样的树, 效率低。 SAX解析器的优点是解析速度快,占用内存少,效率高。

       DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。DOM,它是生成一个树,有了树以后你搜索、查找都可以做。

       SAX,它是基于流的,就是解析器从头到尾解析一遍xml文件,解析完了以后你不过想再查找重新解析。 sax解析器核心是事件处理机制。例如解析器发现一个标记的开始标记时,将所发现的数据会封装为一个标记开始事件,并把这个报告给事件处理器。平时工作中,xml解析你是使用什么?JDOM、DOM4J

20 Java中有哪些解析XML的类库?有什么特点?

 1. DOM(Document Object Model)

  • 符合官方 W3C 标准
  • 是以层次结构组织的节点
  • 可以在层次结构中寻找特定信息
  • 需要加载整个文档、构造层次结构

优点:可获取和操作 xml 任意部分的结构和数据

缺点:需加载整个 XML 文档,消耗资源大

2. SAX(Simple API for XML)

SAX 解析器基于事件的模型,解析 XML 文档时可以触发一系列事件,解析到期望的节点,可以激活一个回调方法,处理该节点上的数据

优点:

  • 不需要全部加载完 XML 文档,可以在达到期望条件时停止解析
  • 对内存的要求较低,能解析占用存储较大的文档
  • 可以一边加载 XML,一边解析
  • 解析 XML 效率和性能较高

缺点:

  • 需要开发者负责节点的处理逻辑,文档越复杂程序就越复杂
  • 按照 XML 内容单向解析,无法直接定位文档层次,很难同时访问同一个文档中的多处不同数据

3. JDOM(Java-based Document Object Model)

JDOM 自身不包含解析器,使用 SAX2 解析器来解析和验证输入XML文档

包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型、XML 文本文档

优点:API 简单,方便开发

缺点:灵活性较差;性能较差

4. DOM4J(Document Object Model for Java)

  • dom4j 包含了超出 XML 文档表示的功能
  • 支持 XML Schema
  • 支持大文档或流化文档的基于事件的处理
  • 可以选择按照 DOM 或 SAX 方式解析 XML 文档

优点:

  • API丰富易用,较直观,方便开发
  • 支持 XPath
  • 性能较好

缺点:

  • 接口较多,API 较为复杂

总结

  • DOM4J 性能最佳
  • JDOM 和 DOM 性能不佳,大文档易内存溢出,但可移植。小文档可考虑使用 DOM 和 JDOM
  • XML 文档较大且不考虑移植性问题可用 DOM4J
  • 无需解析全部 XML 文档,可用 SAX
  1. XML文档定义有几种形式?有何区别?

21 XML文档定义分为 Schema 和 DTD 两种形式

  • Schema 是对XML文档结构的定义和描述,其主要的作用是用来约束XML文件,并验证XML文件有效性。
  • DTD 的作用是定义XML的合法构建模块,它使用一系列的合法元素来定义文档结构。

区别:

  • Schema 本身也是 XML 文档,DTD 定义跟 XML 无关
  • Schema 文档结构性强,各元素之间的嵌套关系非常直观;DTD 文档的结构是"平铺型"的,如果定义复杂的XML文档,很难把握各元素之间的嵌套关系
  • Schema 可以定义元素文本的具体类型; TD 只能指定元素含有文本
  • Schema 支持元素节点顺序的描述;DTD 没有提供无序情况的描述
  • Schema 可以很好满足命名空间;DTD 不可以

22 Java1.7与1.8,1.9,10 新特性

1.5

  1. 自动装箱与拆箱
  2. 枚举(常用来设计单例模式)
  3. 静态导入
  4. 可变参数
  5. 内省

1.6

  1. Web服务元数据
  2. 脚本语言支持
  3. JTable的排序和过滤
  4. 更简单,更强大的JAX-WS
  5. 轻量级Http Server
  6. 嵌入式数据库 Derby

1.7

  1. switch中可以使用字串了
  2. 运用List tempList = new ArrayList<>(); 即泛型实例化类型自动推断
  3. 语法上支持集合,而不一定是数组
  4. 新增一些取环境信息的工具方法
  5. Boolean类型反转,空指针安全,参与位运算
  6. 两个char间的equals
  7. 安全的加减乘除
  8. map集合支持并发请求,且可以写成 Map map = {name:"xxx",age:18};

1.8

  1. 允许在接口中有默认方法实现
  2. Lambda表达式
  3. 函数式接口
  4. 方法和构造函数引用
  5. Lambda的范围
  6. 内置函数式接口
  7. Streams
  8. Parallel Streams
  9. Map
  10. 时间日期API
  11. Annotations

1.9

  1. Jigsaw 项目;模块化源码
  2. 简化进程API
  3. 轻量级 JSON API
  4. 钱和货币的API
  5. 改善锁争用机制
  6. 代码分段缓存
  7. 智能Java编译, 第二阶段
  8. HTTP 2.0客户端
  9. Kulla计划: Java的REPL实现

10

  1. 本地变量类型推断
  2. 统一JDK仓库
  3. 垃圾回收器接口
  4. G1的并行Full GC
  5. 应用程序类数据共享
  6. ThreadLocal握手机制

23 JDK8中Stream接口的常用方法

     Stream 接口中的方法分为中间操作和终端操作,具体如下。

中间操作:

  1. filter:过滤元素
  2. map:映射,将元素转换成其他形式或提取信息
  3. flatMap:扁平化流映射
  4. limit:截断流,使其元素不超过给定数量
  5. skip:跳过指定数量的元素
  6. sorted:排序
  7. distinct:去重

终端操作:

  1. anyMatch:检查流中是否有一个元素能匹配给定的谓词
  2. allMatch:检查谓词是否匹配所有元素
  3. noneMatch:检查是否没有任何元素与给定的谓词匹配
  4. findAny:返回当前流中的任意元素(用于并行的场景)
  5. findFirst:查找第一个元素
  6. collect:把流转换成其他形式,如集合 List、Map、Integer
  7. forEach:消费流中的每个元素并对其应用 Lambda,返回 void
  8. reduce:归约,如:求和、最大值、最小值
  9. count:返回流中元素的个数

24 JNI的使用

      JNI是 Java Native Interface 的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。

25 什么是JAVA内部类?

  25.1、概念

       存在于Java类的内部的Java类。

  25.2、分类

  • 成员内部类
  • 格式
class OuterClass {
    class InnerClass {} //成员内部类
}

        编译之后会生成两个class文件:OuterClass.class和OuterClass$InnerClass.class

  • 方法内部类
  • 格式
class OuterClass {
    public void doSomething(){
        class Inner{
        }
    }
}

      编译之后会生成两个class文件:OuterClass.class和OuterClass$1InnerClass.class

      只能在定义该内部类的方法内实例化

      方法内部类对象不能使用该内部类所在方法的非final局部变量

      当一个方法结束,其栈结构被删除,局部变量成为历史。但该方法结束后,在方法内创建的内部类对象可能仍然存在于堆中 

  • 匿名内部类
  • a) 继承式匿名内部类格式
public class Fish {
	/**
	 * 游泳方法
	 */
	public void swim() {
		System.out.println("我在游泳!");
	}
	public static void main(String[] args) {
		//创建鱼对象
		Fish fish = new Fish() {
			//重写swim方法
			public void swim() {
				System.out.println("我在游泳,突然发生海啸,我撤了!");
			}
		};
		
		fish.swim();
	}
}

      编译后生成两个class文件:Fish.class和Fish$1.class

      b) 接口式匿名内部类格式

interface IFish {
	public void swim();
}
class TestIFish {
	
	public static void main(String[] args) {
		IFish fish = new IFish() {
			@Override
			public void swim() {
				System.out.println("我是一条小丑鱼,我在游泳");
			}
		};
		
		fish.swim();
	}
}

       编译后生成3个class文件:IFish.class、TestIFish.class和TestIFish$1.class

       接口式的匿名内部类是实现了一个接口的匿名类,感觉上实例化了一个接口。

c) 参数式的匿名内部类

  格式

public class TestCrucian {
	
	public static void main(String[] args) {
		Crucian c = new Crucian();
		c.swim(new IFish() {
			@Override
			public void swim() {
				System.out.println("鲫鱼在河水里游泳!");
			}
			
		});
	}
}
/**
 * 鲫鱼游泳
 * @author Lee
 * 2020年8月13日上午9:41:01
 */
class Crucian {
	/**
	 * 鲫鱼的游泳方法
	 * @param fish
	 */
	void swim(IFish fish) {
		fish.swim();
	}
}

    编译后生成3个class文件:Crucian.class、TestCrucian.class和TestCrucian$1.class 

  • 静态嵌套类
  • 静态嵌套类,并没有对实例的共享关系,仅仅是代码块在外部类内部
  • 静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它
  • 静态嵌套类仅能访问外部类的静态成员和方法
  • 在静态方法中定义的内部类也是静态嵌套类,这时候不能在类前面加static关键字
  • 格式

          25.4、特点

  • class OuterFish {
    	/**
    	 * 静态嵌套类
    	 * @author Lee
    	 * 2020年8月13日上午10:57:52
    	 */
    	static class InnerFish {
    	}
    }
    class TestStaticFish {
    	
    	public static void main(String[] args) {
    		//创建静态内部类对象
    		OuterFish.InnerFish iFish = new OuterFish.InnerFish();
    	}
    }
    

            25.3、内部类的作用

  •     内部类提供了某种进入其继承的类或实现的接口的窗口
  •     与外部类无关,独立继承其他类或实现接口
  •      内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号
  •      内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的
  •       内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量
  •      内部类提供了Java的"多重继承"的解决方案,弥补了Java类是单继承的不足

26 匿名内部类可以继承类或实现接口吗?为什么?

  1. 匿名内部类本质上是对父类方法的重写 或 接口的方法的实现
  2. 从语法角度看,匿名内部类创建处是无法使用关键字继承类 或 实现接口

原因:

  1. 匿名内部类没有名字,所以它没有构造函数。因为没有构造函数,所以它必须通过父类的构造函数来实例化。即匿名内部类完全把创建对象的任务交给了父类去完成。
  2. 匿名内部类里创建新的方法没有太大意义,新方法无法被调用。
  3. 匿名内部类一般是用来覆盖父类的方法。
  4. 匿名内部类没有名字,所以无法进行向下的强制类型转换,只能持有匿名内部类对象引用的变量类型的直接或间接父类。

27 内部类可以引用它的外部类的成员吗?有什么限制?

  1. 内部类对象可以访问创建它的外部类对象的成员,包括私有成员
  2. 访问外部类的局部变量,此时局部变量必须使用 final 修饰

28 java如何实现其他语言的高阶函数

     JDK的特性Lambda表达式

什么是高阶函数

      高阶函数是指接受另外一个函数作为参数,或返回一个函数的函数。什么样的参数是函数类型的参数?要看该参数是否是一个函数式接口,函数式接口只会有一个方法,会使用 @FunctionalInterface 这个注解来修饰。

高阶函数在 Java8 中很常见,如以下的例子:

Stream<Integer> numUp = Stream.of(1, 2, 5).map(num -> num += 1);
Stream<Integer> numbers = Stream.of(1, 2, -1, -5).filter(n -> n > 0);

如何判断高阶函数

  Stream 的 anyMatch 是高阶函数吗?是的。因为它的参数接收的是另外一个函数:Predicate。

boolean greaterThanZero = Stream.of(-1, -2, 0, -5).anyMatch(num -> num > 0);

  Stream 的 limit 是高阶函数吗?是的。因为它的返回值是一个Stream。

Stream<Integer> onlyTwoNumbers = Stream.of(-1, -2, 0, -5).limit(2);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值