目录

java水平提升记录

以下是我不熟的

  1. try with resource:

    • 语法格式:try( Scanner scanner=new Scanner){ // scan } finally {scanner.close();}
      • 不写catch。 编译器会自动在finally里面加 变量.close()
      • 语法糖
    • 需要对象本身实现了 java.lang.AutoCloseable
    • 优点: 比使用finalize 回收对象更可控
  2. 构造函数赋值: 使用双花括号可以实现类似 with的效果,不用写 this.

    • 语法格式: Person = new Person(){{ name = 'abc'; age=11;}}
    • 用途: 针对没有相应构造函数,但是又要赋值的情况。
  3. 内部类:

    • 定义和声明:把一个类的声明 class InnerExample 放到另外一个类里面
      • 编译器会生成 xxx$xxx 这样的class文件
      • 内部类不能和外部类重名
    • 使用:
      • 在封装内部类的内部使用跟其他普通类没差别
      • 在其他地方使用:
        • 类名前要冠以外部类的名字
        • 在用new创建内部类的时候,也要在new 前面冠以对象变量: 外部对象名.new 内部类名(参数)
    • 注意:
      • 内部类可以访问外部类的字段和方法,即使private的也可以
      • 当内部类中有和外部类同名的字段或方法,可以用 外部类名.this.字段及方法
      • 内部类可以用public protected,private 修饰符,外部类只能用public或者默认
      • 内部类可以用 final, abstract 修饰符
      • 用static修饰符定义内部类的时候,它实际被声明成为了外部类(有人认为这是嵌套类)
      • 当使用static类的时候:
        • 实例化的时候,new签名不需要对象实例变量(因为static跟实例无关)
        • static类中不能访问其外部类的非static字段和方法,只能访问static成员
        • static方法中不能访问非static的域及方法,也不能不带前缀地new 一个非static的内部类
  4. 局部类(在方法里面定义的类 local class)

    • 注意:
      • 不能用public private protected static修饰
      • 可以用final 或者abstract修饰
      • 可以访问其外部类的成衣
      • 不能访问局部变量,除非它是final的
  5. 匿名类: 一种特殊的内部类(anonymous class)

    • 定义:
      • 定义和创建同时使用和完成,类的定义前面有一个new
        • new 类名 或接口名 (){......}
        • 不使用关键字class,也不使用extends 及 implements
      • 不取名字,直接用其父类或接口的名字,该类是父类的子类,或者实现了一个接口
      • 编译器生成 xxxxx$1 之类的名字
      • 在构造对象的时候使用父类构造方法
    • 典型应用:
      1. 界面的事件处理:
        1. uiObj.addActionListener(someAction)
        2. uiObj.addActionListener(new ActionListener(){ public void actionPerformed(Event e){ /事件处理代码/ } });
      2. 作为方法的参数:eg排序,实现一个比较大小的接口
        1. Arrays.sort(books, new Comparator(){ public int compare(Book b1, Book b2){ return b1.price - b2.price; } });
    • 类似闭包
  6. Lambda表达式:

    • 信息:Lambda expression.
      • 大体上相当于其他语言的"匿名函数" 或 "函数指针"
      • java中他实际上是"匿名类的一个实例"
    • 写法: (参数)->结果
    • eg:
      • (String s) -> s.length()
      • () -> { System.out.println("abc"); }
      • x -> x*x
      • 求积分例子: double d = Integra( x-> Math.sin(x), 0, Math.PI, 1e-5);
    • 意义:
      • Lambda表达式大大简化了书写:线程,积分函数,按钮事件处理 等等
    • 限制:
      • 能写成 Lambda表达式的接口 要求 **包含且最多只能有一个 ** 抽象函数
      • 这样的接口可以(但不强制)用注记:
    • 总结:
      • Lambda表达式 是 接口 或者 接口函数的简写
  7. 高级语法:装箱,枚举,注解

    • 信息:从JDK 1.5开始增加的一些新的语法糖
      • 基本类型的包装类:将基本类型(Primitive type )包装成 Object(引用类型)
      • 共8类:Boolean, Byte, Short, Character, Integer, Long, Float, Double
    1. 装箱(Boxing)和拆箱(Unboxing)
      • 把基本类型直接赋值给引用类型 Integer I = 10; int i=I;
        • 翻译为: Integer I = Integer.valueOf(10); Object [] ary = {1, "aaa};
    2. 枚举(enum) 是一种特殊的class类型
      • 写法: enum Lignt {Red, Yellow, Green}; , Light light = Light.Red;
      • 实际上生成了: class Light extends java.lang.Enum
      • 可以在enum定义体重,添加 字段,方法,构造方法
    3. 注解(annotation) 注记,标记,标注,用于在各种语法要素删加上附加信息,供编译器和其他程序使用
  8. java语言的"指针":引用与指针:

    • 信息:
      1. 引用(reference)实质上就是指针(point)
      2. 引用是受控的,安全的:
        1. 会检查空指针
        2. 没有指针运算 *(p+5)
        3. 不能访问没有引用到的内存
        4. 自动回收垃圾
    • 变通: 数组,指向节点,JNI
    • 判断是否相等:
      • 简单来说: 基本类型:比较值相等 引用类型:引用相等
      • 具体判断:
        • 数值类型:转换后比较
        • 浮点数:最好不直接用 ==, 判断差的绝对值是否很小
        • Double.NAN == Double.NAN 结果是false, 见文档
        • boolean 和int无法比较
        • 枚举类型:可以直接比较,因为内部进行了唯一实例化
        • 引用对象:
          • 直接比较连个引用是否一样
          • 如果要判断内容是否一样,要重写 equals() 方法
          • 如果重写equals方法,最好也重写 hashCode() 方法
        • String 相等:
          • 判断的时候一定不要用 ==,要用equals
          • 但是,字符串常量(string literal)和字符串常量会进行内部化( interned),相同的字符串常量是相等的
  9. java的异常:

    • 分为两种: 运行时异常(及其子类), 受检异常
      • 运行时异常(及其子类)可以不明确处理
      • 受检异常,必须明确进行语法处理,要么捕获 catch,要么抛出 throws
    • 子类如果覆盖了父类的一个方法,子类可以抛出子类异常(更具体的异常),但是不能抛出更一般的异常
    • 自定义异常:
      • 继承自 Exception 或者 某个Exception的子类
      • 异常的链接:
        • 处理异常以后如果需要再次抛出,可以抛出当前异常,可以抛出另一个异常,也可以抛出一个新异常,并把当前异常的cause()作为内部异常一起抛出
  10. 断言和测试:

    1. 断言: assertion
      • 格式: assert 表达式; 或者 assert 表达式:信息;
    2. 测试: JUnit
  11. Java的错误 Error:

    1. 分类: 语法错误(Syntax error), 运行错误(Runtime error), 逻辑错误(Logic error)
  12. 集合,排序:

    1. list和set的区别
      1. List: (Collection的子接口)记录元素的保存顺序, 且允许有重复元素
      2. Set: (Collection的子接口) 不记录元素的保存顺序,且不允许有重复元素
  13. 多线程:

    1. 实现方法:
      1. extends Thread
      2. implements Runnable
      3. 用匿名类, new Thread(){ public void run(){ /* 内容*/ } }
      4. 用lambda表达式, new Thread( ()->{ /* 内容*/ } ).start();
    2. 对线程的控制
      1. 启动: .start()
      2. 结束: . 设定标记变量
      3. 阻止执行
      4. 设定优先级:
    3. 线程类型:
      1. 普通线程(非 deamon线程): 如果一个java程序中还存在deamon线程,程序就不会结束
      2. daemon线程(守护线程,后台线程): 不阻止程序结束
        1. setDaemon(true);
    4. 线程的同步:
      1. 原因: 线程的不确定性: eg: cnt++ 的例子
      2. 概念: 互斥锁:
      3. 用法: synchronized(代码片段) synchronized 方法
        1. 使用 wait() 方法可以释放对象锁
        2. 使用 notify() 或 notifyAll() 可以让等待的一个或所有线程进入就绪状态
      4. 在Java中可以讲wait和notify放在synchronized里面,因为java是这样处理的:
        • 在 synchronized代码执行期间,线程调用对象的wait()方法,会释放对象锁标志,然后进入等待状态,然后由其他线程调用notify()或者notifyAll()方法通知正在等待的线程
      5. 为了避免问题,方便使用,JDK1.5中增加了更多的类,以便更灵活的使用锁机制
        1. java.util.concurrent.locks 包
        2. Lock接口, ReentrantLock 类 : lock() tryLock() unlock()
        3. ReadWriteLock接口, ReentrantReadWriteLock类 .writeLock().lock() .readLock().unlock()
  14. 并发API

    1. 来自: java.util.concurrent包及子包
      • 从JDK1.5开始,提供了一系列的工具,更好更方便地使用线程
      • 实用类: 单变量, 集合, Timer, 线程池
      • 集合与线程:
        • ArrayList/ HashMap是线程不安全的 ----> Vector 和HashTable是线程安全的
        • 产生一个线程安全的集合对象 Collections.synchronizedArrayList(list) // 相对安全一些
      • 方便使用的线程安全类:
        • CopyOnWriteArrayList CopyOnWriteArraySet 适用于很少写入而读取频繁的对象
        • ConcurrentHashMap : putIfAbsent(), remove(), replace()
        • ArrayBlockingQueue: 生产者与消费者, 使用put()及 take()
    2. 原子类型(线程安全) java.util.concurrent.atomic
    3. 线程池:
      1. 相关类: ExecutorService接口, ThreadPoolExecutor 类, Executors工具类
      2. 常见用法: ExecutorService pool = Executors.newCachedThreadPool(); 使用其 execute(Runnable r)方法
    4. Timer 计时器: java.util.Timer 重复某件事, javax.swing.Timer类 重复执行 ActionListener
      1. 特别注意: 在线程中更新图形化界面,要调用 SwingUtilites.invokeLater
  15. 流式操作和并行流: 流式操作 ≈ 流水线操作, 函数式风格的操作

    1. 类似 js的 underscore / lodash
    2. 流操作分成两类:
      1. 中间的: 保持流打开状态,并允许后续操作: filter, sorted, limit, map
      2. 末端的: 必须是对流的最终操作: max, min, count, forEach, findAny
    3. 步骤:获取流,中间操作,末端操作
      1. 数组: Arrays.stream(ary)
      2. Collection(包括List) list.stream()
      3. Map: 没有流,但是有类似方法: map.putIfAbsent map.computeIfPresent map.merge
      4. Stream的子接口: DoubleStream, IntStream, LongStream, Stream
      5. 并行计算: 只需要把 .stream() 换成 .parallelStream() 其他都不变,就可以实现并行计算
  16. 输入输出:

    1. 信息:java.io/ java.nio / java.nio2 文件流,内存流,网络流, 字符流/字符流, 节点流/处理流(过滤流)

      • 输入: 字节流: InputStream 字符流: Reader
      • 输出: 字节流: OutputStream 字符流: Writer
    2. 常用类:

      1. InputStream 类 read()方法, 逐字节地以二进制原始方式读入数据
      2. OutputStream 类 write()方法,
      3. Reader 类
      4. Writer 类
      5. java.util.Scanner 类:(JDK1.5+)
      6. java.nio.file.Files -> readAllLines() 方法
    3. 常见节点流:

    4. 概念:

      1. 流的包装(链接):一个流对象经过其他流的多次包装,称为流的链接。
        • 处理流的构造方法总是要带一个其他的流对象作为参数
        • eg. BufferedReader in2 = new BufferedReader( newInputStreamReader( new FileInputStream(file), "utf-8"));
          • 从字节的 FileInputStream包装成 字符的 InputStreamReader,最后包装成BufferedReader以后,我们就可以执行 in2.readLine();
      2. 获取字符集: Charset.forName("utf8")
    5. 对象的读写: 序列号与反序列化

      1. 使用的类:
        1. 对象: ObjectInputStream, ObjectOutputStream
        2. 基本数据: DataInputStream, DataOutputStream
      2. 必须实现 Serializable 接口,才能实现序列化与反序列化:
        1. 该接口没有方法,只是一个标记
  17. 网络流

    1. 概念
    2. 常用类: URL,
  18. 文件流:

    1. 概念
    2. 常用类: File( 目录也当成File处理), RandomAccessFile
  19. 正则表达式:

    1. 概念: 用于匹配字符串的一种模式 字符{数量}位置
    2. 写法:
    3. 常用类:

以下都是正确的说法

  1. 父类的非私有方法可以被子类自动继承。
  2. 字段变量可以自动赋初值。
  3. 多态是指一个程序中相同的名字表示不同的含义的情况。
  4. 系统在回收垃圾时会自动调用对象的finalize() 方法。
  5. try-with-resources语句可以自动执行close()方法。
  6. Error是Throwable的子类。
  7. Java方法签名包括: 方法头指定修饰符(例如static)、返回值类型、方法名、和形式参数。
  8. Java子类中,使用super访问父类的域和方法 super.attributName = 1; super.parentClassFunction();
  9. java中 final所修饰的变量,是只读量
    • 当使用final修饰变量时,表示该变量是不可改变的
      1. 一个永不改变的编译时常量
      2. 一个在运行时才被赋初值的变量,但不希望该变量的值被修改
  10. 在接口中定义的方法具有public, abstract的特点(Java8以前)
    • 在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的
    • JDK8及以后,允许我们在接口中定义static方法和default方法。
      • 如果两个接口中定义了一模一样的默认方法,并且一个实现类同时实现了这两个接口,那么必须在实现类中重写默认方法,否则编译失败
  11. SimpleDateFormat类可以用来解析日期字符串。 是的, 用parse() 返回Date对象
  12. TreeMap的底层实现是红黑树
  13. Set的主要实现包括HashSet及TreeSet
  14. 迭代的基本模式是while(){ x=f(x); }。
  15. List会记录元素的保存顺序。
  16. List的主要实现包括LinkedList及ArrayList
  17. Queue的主要实现包括LinkedList
  18. for-each语句可以用于所有的Collection及数组。
  19. list和set的区别
    1. List中允许插入重复的元素,而在Set中不允许重复元素存在。 ​
    2. List是有序集合,会保留元素插入时的顺序,Set是无序集合。 ​
    3. List可以通过下标来访问,而Set不能。
  20. Java的集合框架体系总结
    1. Iterator被xxx实现: Collection, ListIterator, Map
    2. Collection 被 Set List 实现
    3. Set 被 HashSet TreeSet 实现
    4. List 被 ArrayList LinkedList 实现
    5. Map 被 HashMap, TreeMap(红黑树)实现
    6. HashSet 被 LinkedHashSet 实现/继承
    7. HashMap 被 LinkedHashMap 实现/继承
    8. Vector HashTable 均已经被替代
    9. java集合继承关系图
  21. 早期类或接口的新版替换:
    1. Vector -> ArrayList 相当于动态数组, 有elementAt
    2. Stack -> LInkedList Stack是Vector的子类,push,pop, peek
    3. Hashtable -> HashMap Hashtable 实现了Map接口,参见Properties类
    4. Enumeration -> Iterator
      • Enumeration用另一种方式实现Iterator功能
  22. 1.

以下都是错误的说法:

  1. 如果一个类被abstract所修饰,说明这个类没有构造方法
    • 例子
      • 抽象类的构造方法定义为protected,因为他只能被子类使用,即用super(params);
  2. protected修饰的成员,不能在包中访问,只能在子类中访问。
    • 示意图
  3. private可以修饰类、也可以修饰类的成员(字段、方法)。
    • private只能修饰内部类,不能修饰外部类
    • private关键字只能修饰内部类,不能修饰外部类。 但是,这个地方一定要注意了:内部类中方法只能是static的,因此,内部类也要声明为静态的!
  4. 虚方法调用是指编译时就决定了调用哪个类中的哪个方法。
    • 运行时才知道
  5. instanceof是判断一个对象实例是不是某种类型及其父类型。
    • 只判断一种类型
  6. 抽象类不能有构造方法。
    • 可以有
  7. 匿名类可以定义构造方法。
    • 不可以
  8. 编译器会为所有的类加一个default构造方法,即使用户已定义了构造方法。
    • 用户不写构造方法的时候编译器才会加一个默认的
  9. finally语句是指没有异常出现时要执行的语句。
    • NO
  10. 构造方法(constructor )的返回类型是void。
    • 错误,返回值是构造方法所在类,这个类型的对象
  11. 如果省略访问控制符,则表示private
    • 错误,表示friendly, 包内使用 (待确认)
  12. String 与数组一样,有一个属性叫length。
    • 错误。 string.length() 是方法不是属性。 数组 ( String[] arr ) 才有 .length 属性
  13. String a = "abcdef"; 则a.substring(1,3)的结果为"bcd"。
    • 错误, java的 String.substring 方法的两个参数,是起始和结束位置,不是起始位置和长度
  14. for-each语句可以用于所有的Enumerable对象。
    • 错误
666    ·   1

(点赞功能开发中)

评论列表
{{item.userName}}
{{item.lastUpdate}}
{{item.content}}
{{item.like}}    |   {{item.unlike}}
{{ sItem.userName }}
{{ sItem.lastUpdate }}
{{ sItem.content }}
{{ sItem.like }}    |   {{ sItem.unlike }}