java水平提升记录
以下是我不熟的
try with resource:
- 语法格式:
try( Scanner scanner=new Scanner){ // scan } finally {scanner.close();}
- 不写catch。 编译器会自动在finally里面加 变量.close()
- 语法糖
- 需要对象本身实现了 java.lang.AutoCloseable
- 优点: 比使用finalize 回收对象更可控
- 语法格式:
构造函数赋值: 使用双花括号可以实现类似 with的效果,不用写
this.
- 语法格式:
Person = new Person(){{ name = 'abc'; age=11;}}
- 用途: 针对没有相应构造函数,但是又要赋值的情况。
- 语法格式:
内部类:
- 定义和声明:把一个类的声明 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的内部类
- 定义和声明:把一个类的声明 class InnerExample 放到另外一个类里面
局部类(在方法里面定义的类 local class)
- 注意:
- 不能用public private protected static修饰
- 可以用final 或者abstract修饰
- 可以访问其外部类的成衣
- 不能访问局部变量,除非它是final的
- 注意:
匿名类: 一种特殊的内部类(anonymous class)
- 定义:
- 定义和创建同时使用和完成,类的定义前面有一个new
new 类名 或接口名 (){......}
- 不使用关键字class,也不使用extends 及 implements
- 不取名字,直接用其父类或接口的名字,该类是父类的子类,或者实现了一个接口
- 编译器生成 xxxxx$1 之类的名字
- 在构造对象的时候使用父类构造方法
- 定义和创建同时使用和完成,类的定义前面有一个new
- 典型应用:
- 界面的事件处理:
- uiObj.addActionListener(someAction)
- uiObj.addActionListener(new ActionListener(){ public void actionPerformed(Event e){ /事件处理代码/ } });
- 作为方法的参数:eg排序,实现一个比较大小的接口
- Arrays.
sort(books, new Comparator (){ public int compare(Book b1, Book b2){ return b1.price - b2.price; } });
- Arrays.
- 界面的事件处理:
- 类似闭包
- 定义:
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表达式的接口 要求 **包含且最多只能有一个 ** 抽象函数,
- 这样的接口可以(但不强制)用注记:
- @FunctionalInterface 来表示,称为函数式接口
- 总结:
- Lambda表达式 是 接口 或者 接口函数的简写
- 信息:Lambda expression.
高级语法:装箱,枚举,注解
- 信息:从JDK 1.5开始增加的一些新的语法糖
- 基本类型的包装类:将基本类型(Primitive type )包装成 Object(引用类型)
- 共8类:Boolean, Byte, Short, Character, Integer, Long, Float, Double
- 装箱(Boxing)和拆箱(Unboxing)
- 把基本类型直接赋值给引用类型 Integer I = 10; int i=I;
- 翻译为:
Integer I = Integer.valueOf(10);
Object [] ary = {1, "aaa};
- 翻译为:
- 把基本类型直接赋值给引用类型 Integer I = 10; int i=I;
- 枚举(enum) 是一种特殊的class类型
- 写法:
enum Lignt {Red, Yellow, Green};
,Light light = Light.Red;
- 实际上生成了:
class Light extends java.lang.Enum
- 可以在enum定义体重,添加 字段,方法,构造方法
- 写法:
- 注解(annotation) 注记,标记,标注,用于在各种语法要素删加上附加信息,供编译器和其他程序使用
- 信息:
- 所有注解,都是 java.lang.annotation.Annotation的子类
- 常用注解:
- 自定义注解: 见教材
- 信息:
- 信息:从JDK 1.5开始增加的一些新的语法糖
java语言的"指针":引用与指针:
- 信息:
- 引用(reference)实质上就是指针(point)
- 引用是受控的,安全的:
- 会检查空指针
- 没有指针运算 *(p+5)
- 不能访问没有引用到的内存
- 自动回收垃圾
- 变通: 数组,指向节点,JNI
- 判断是否相等:
- 简单来说: 基本类型:比较值相等 引用类型:引用相等
- 具体判断:
- 数值类型:转换后比较
- 浮点数:最好不直接用 ==, 判断差的绝对值是否很小
- Double.NAN == Double.NAN 结果是false, 见文档
- boolean 和int无法比较
- 枚举类型:可以直接比较,因为内部进行了唯一实例化
- 引用对象:
- 直接比较连个引用是否一样
- 如果要判断内容是否一样,要重写 equals() 方法
- 如果重写equals方法,最好也重写 hashCode() 方法
- String 相等:
- 判断的时候一定不要用 ==,要用equals
- 但是,字符串常量(string literal)和字符串常量会进行内部化( interned),相同的字符串常量是相等的
- 信息:
java的异常:
- 分为两种: 运行时异常(及其子类), 受检异常
- 运行时异常(及其子类)可以不明确处理
- 受检异常,必须明确进行语法处理,要么捕获 catch,要么抛出 throws
- 子类如果覆盖了父类的一个方法,子类可以抛出子类异常(更具体的异常),但是不能抛出更一般的异常
- 自定义异常:
- 继承自 Exception 或者 某个Exception的子类
- 异常的链接:
- 处理异常以后如果需要再次抛出,可以抛出当前异常,可以抛出另一个异常,也可以抛出一个新异常,并把当前异常的cause()作为内部异常一起抛出
- 分为两种: 运行时异常(及其子类), 受检异常
断言和测试:
- 断言: assertion
- 格式:
assert 表达式;
或者assert 表达式:信息;
- 格式:
- 测试: JUnit
- 断言: assertion
Java的错误 Error:
- 分类: 语法错误(Syntax error), 运行错误(Runtime error), 逻辑错误(Logic error)
集合,排序:
- list和set的区别
- List: (Collection的子接口)记录元素的保存顺序, 且允许有重复元素
- Set: (Collection的子接口) 不记录元素的保存顺序,且不允许有重复元素
- list和set的区别
多线程:
- 实现方法:
- extends Thread
- implements Runnable
- 用匿名类,
new Thread(){ public void run(){ /* 内容*/ } }
- 用lambda表达式,
new Thread( ()->{ /* 内容*/ } ).start();
- 对线程的控制
- 启动: .start()
- 结束: . 设定标记变量
- 阻止执行
- 设定优先级:
- 线程类型:
- 普通线程(非 deamon线程): 如果一个java程序中还存在deamon线程,程序就不会结束
- daemon线程(守护线程,后台线程): 不阻止程序结束
- setDaemon(true);
- 线程的同步:
- 原因: 线程的不确定性: eg: cnt++ 的例子
- 概念: 互斥锁:
- 用法: synchronized(代码片段) synchronized 方法
- 使用 wait() 方法可以释放对象锁
- 使用 notify() 或 notifyAll() 可以让等待的一个或所有线程进入就绪状态
- 在Java中可以讲wait和notify放在synchronized里面,因为java是这样处理的:
- 在 synchronized代码执行期间,线程调用对象的wait()方法,会释放对象锁标志,然后进入等待状态,然后由其他线程调用notify()或者notifyAll()方法通知正在等待的线程
- 为了避免问题,方便使用,JDK1.5中增加了更多的类,以便更灵活的使用锁机制
- java.util.concurrent.locks 包
- Lock接口, ReentrantLock 类 : lock() tryLock() unlock()
- ReadWriteLock接口, ReentrantReadWriteLock类 .writeLock().lock() .readLock().unlock()
- 实现方法:
并发API
- 来自: java.util.concurrent包及子包
- 从JDK1.5开始,提供了一系列的工具,更好更方便地使用线程
- 实用类: 单变量, 集合, Timer, 线程池
- 集合与线程:
- ArrayList/ HashMap是线程不安全的 ----> Vector 和HashTable是线程安全的
- 产生一个线程安全的集合对象 Collections.synchronizedArrayList(list) // 相对安全一些
- 方便使用的线程安全类:
- CopyOnWriteArrayList CopyOnWriteArraySet 适用于很少写入而读取频繁的对象
- ConcurrentHashMap : putIfAbsent(), remove(), replace()
- ArrayBlockingQueue: 生产者与消费者, 使用put()及 take()
- 原子类型(线程安全) java.util.concurrent.atomic
- 线程池:
- 相关类: ExecutorService接口, ThreadPoolExecutor 类, Executors工具类
- 常见用法: ExecutorService pool = Executors.newCachedThreadPool(); 使用其 execute(Runnable r)方法
- Timer 计时器: java.util.Timer 重复某件事, javax.swing.Timer类 重复执行 ActionListener
- 特别注意: 在线程中更新图形化界面,要调用 SwingUtilites.invokeLater
- 来自: java.util.concurrent包及子包
流式操作和并行流: 流式操作 ≈ 流水线操作, 函数式风格的操作
- 类似 js的 underscore / lodash
- 流操作分成两类:
- 中间的: 保持流打开状态,并允许后续操作: filter, sorted, limit, map
- 末端的: 必须是对流的最终操作: max, min, count, forEach, findAny
- 步骤:获取流,中间操作,末端操作
- 数组: Arrays.stream(ary)
- Collection(包括List) list.stream()
- Map: 没有流,但是有类似方法: map.putIfAbsent map.computeIfPresent map.merge
- Stream的子接口: DoubleStream, IntStream, LongStream, Stream
- 并行计算: 只需要把 .stream() 换成 .parallelStream() 其他都不变,就可以实现并行计算
输入输出:
信息:java.io/ java.nio / java.nio2 文件流,内存流,网络流, 字符流/字符流, 节点流/处理流(过滤流)
- 输入: 字节流: InputStream 字符流: Reader
- 输出: 字节流: OutputStream 字符流: Writer
常用类:
- InputStream 类 read()方法, 逐字节地以二进制原始方式读入数据
- OutputStream 类 write()方法,
- Reader 类
- Writer 类
- java.util.Scanner 类:(JDK1.5+)
- java.nio.file.Files -> readAllLines() 方法
常见节点流:
概念:
- 流的包装(链接):一个流对象经过其他流的多次包装,称为流的链接。
- 处理流的构造方法总是要带一个其他的流对象作为参数
- eg.
BufferedReader in2 = new BufferedReader( newInputStreamReader( new FileInputStream(file), "utf-8"));
- 从字节的 FileInputStream包装成 字符的 InputStreamReader,最后包装成BufferedReader以后,我们就可以执行
in2.readLine();
- 从字节的 FileInputStream包装成 字符的 InputStreamReader,最后包装成BufferedReader以后,我们就可以执行
- 获取字符集: Charset.forName("utf8")
- 流的包装(链接):一个流对象经过其他流的多次包装,称为流的链接。
对象的读写: 序列号与反序列化
- 使用的类:
- 对象: ObjectInputStream, ObjectOutputStream
- 基本数据: DataInputStream, DataOutputStream
- 必须实现 Serializable 接口,才能实现序列化与反序列化:
- 该接口没有方法,只是一个标记
- 使用的类:
网络流
- 概念
- 常用类: URL,
文件流:
- 概念
- 常用类: File( 目录也当成File处理), RandomAccessFile
正则表达式:
- 概念: 用于匹配字符串的一种模式
字符{数量}位置
- 写法:
- 常用类:
- 概念: 用于匹配字符串的一种模式
以下都是正确的说法
- 父类的非私有方法可以被子类自动继承。
- 字段变量可以自动赋初值。
- 多态是指一个程序中相同的名字表示不同的含义的情况。
- 系统在回收垃圾时会自动调用对象的finalize() 方法。
- try-with-resources语句可以自动执行close()方法。
- Error是Throwable的子类。
- Java方法签名包括: 方法头指定修饰符(例如static)、返回值类型、方法名、和形式参数。
- Java子类中,使用super访问父类的域和方法
super.attributName = 1; super.parentClassFunction();
- java中 final所修饰的变量,是只读量
- 当使用final修饰变量时,表示该变量是不可改变的
- 一个永不改变的编译时常量
- 一个在运行时才被赋初值的变量,但不希望该变量的值被修改
- 当使用final修饰变量时,表示该变量是不可改变的
- 在接口中定义的方法具有public, abstract的特点(Java8以前)
- 在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的
- JDK8及以后,允许我们在接口中定义static方法和default方法。
- 如果两个接口中定义了一模一样的默认方法,并且一个实现类同时实现了这两个接口,那么必须在实现类中重写默认方法,否则编译失败
- SimpleDateFormat类可以用来解析日期字符串。 是的, 用parse() 返回Date对象
- TreeMap的底层实现是红黑树
- Set的主要实现包括HashSet及TreeSet
- 迭代的基本模式是while(){ x=f(x); }。
- List会记录元素的保存顺序。
- List的主要实现包括LinkedList及ArrayList
- Queue的主要实现包括LinkedList
- for-each语句可以用于所有的Collection及数组。
- list和set的区别
- List中允许插入重复的元素,而在Set中不允许重复元素存在。
- List是有序集合,会保留元素插入时的顺序,Set是无序集合。
- List可以通过下标来访问,而Set不能。
- Java的集合框架体系总结
- Iterator被xxx实现: Collection, ListIterator, Map
- Collection 被 Set List 实现
- Set 被 HashSet TreeSet 实现
- List 被 ArrayList LinkedList 实现
- Map 被 HashMap, TreeMap(红黑树)实现
- HashSet 被 LinkedHashSet 实现/继承
- HashMap 被 LinkedHashMap 实现/继承
- Vector HashTable 均已经被替代
- java集合继承关系图
- 早期类或接口的新版替换:
- Vector -> ArrayList 相当于动态数组, 有elementAt
- Stack -> LInkedList Stack是Vector的子类,push,pop, peek
- Hashtable -> HashMap Hashtable 实现了Map接口,参见Properties类
- Enumeration -> Iterator
- Enumeration用另一种方式实现Iterator功能
1.
以下都是错误的说法:
- 如果一个类被abstract所修饰,说明这个类没有构造方法
- 例子
抽象类的构造方法定义为protected,因为他只能被子类使用,即用super(params);
- 例子
- protected修饰的成员,不能在包中访问,只能在子类中访问。
- private可以修饰类、也可以修饰类的成员(字段、方法)。
private只能修饰内部类,不能修饰外部类
private关键字只能修饰内部类,不能修饰外部类。 但是,这个地方一定要注意了:内部类中方法只能是static的,因此,内部类也要声明为静态的!
- 虚方法调用是指编译时就决定了调用哪个类中的哪个方法。
- 运行时才知道
- instanceof是判断一个对象实例是不是某种类型及其父类型。
- 只判断一种类型
- 抽象类不能有构造方法。
- 可以有
- 匿名类可以定义构造方法。
- 不可以
- 编译器会为所有的类加一个default构造方法,即使用户已定义了构造方法。
- 用户不写构造方法的时候编译器才会加一个默认的
- finally语句是指没有异常出现时要执行的语句。
- NO
- 构造方法(constructor )的返回类型是void。
- 错误,返回值是构造方法所在类,这个类型的对象
- 如果省略访问控制符,则表示private
- 错误,表示friendly, 包内使用 (待确认)
- String 与数组一样,有一个属性叫length。
- 错误。 string.length() 是方法不是属性。 数组 (
String[] arr
) 才有 .length 属性
- 错误。 string.length() 是方法不是属性。 数组 (
- String a = "abcdef"; 则a.substring(1,3)的结果为"bcd"。
- 错误, java的 String.substring 方法的两个参数,是起始和结束位置,不是起始位置和长度
- for-each语句可以用于所有的Enumerable对象。
- 错误
666 · 1
(点赞功能开发中)