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
正则表达式:
- 概念: 用于匹配字符串的一种模式
字符{数量}位置
- 写法:
- 常用类: java.util.regex 模式类 Pattern 匹配类 Matcher,
Pattern.matches(pattern, variable)
- Matcher类的方法:
- find方法扫描输入序列,寻找下一个与Pattern匹配的地方
- appendReplacement方法
- Matcher中的group (分组)
- group(分组),是指正则表达式中一对圆括号括起来的一部分
- group(0)或 group()表示整个匹配项, group(1), group(2) 表示各个分组,
- 替换时, $0 表示整个匹配项,$1, $2 … 表示各个分组(圆括号)
- Matcher类的方法:
- 概念: 用于匹配字符串的一种模式
图形用户界面组件及分类:
- 概念:
- AWT: Abstract Window Toolkit
- Swing: JDK 1.2以后引入的,功能更强,界面更丰富,轻量级,各种平台上更统一
- 组件:
- 容器组件, 非容器组件
- 容器: 顶层容器(JFrame, JDialog, JApplet ),非顶层容器
- JComponent: 非顶层容器
- 实现图形三个步骤: 组件Component,布局 Layout,事件 Event,
- 常用类:
- java.awt 包
- Frame, Buttom, Label, TextField, TextArea, Panel
- javax.swing 包
- JFrame, JButton, Jlabel, Jtextfield, JtextArea, JPanel
- java.awt 包
- 写法:
- 事件处理:
- 常用组件:
- JOptionPane: 约等于 dialog
- 概念:
网络编程:
- 概念:
- Socket/ ServerSocket: 客户端和服务端相连的方式
- 常用类:
- java.net.URL
- Appache的 httpclient (外部引用)
- 写法:
- 概念:
多媒体编程:
- 概念:
- Java Media API
- JAI : Java Advanced Imaging
- Java 3D
- JMF : Java Media Framework
- 常用类:
- 组件的 get Graphics()
- Canvas 及 JComponent 对象 -> Canvas的 paint() JComponent 的 paintComponent(Graphics g)
- JPanel -> setDoubleBuffered(true) 画图时间长的情况下,使用双缓存,避免闪烁
- Graphics.drawImage() 显示图像
- javax.imageio.ImageIO.read( new File() ) 载入图片
- BufferedImage 类 后台画图 getGraphics()
- ImageIO read() write()
- 写法:
- 概念:
数据库编程:
- 概念:
- JDBC: Java Database Connectivity. Java8 开始不再支持 ODBC
- 常用类:
- Connection 连接
- Statement 语句
- ResultSet 结果集 next() 遍历所有结果
- PreparedStatement 经过编译的语句 (多次执行相同语句速度略快, 可以方便地加参数, 避免SQL注入攻击 )
- swing.JTable 用于显示的数据表
- 写法:
- 加载驱动程序
Class.forName("org.sqlite.JDBC");
- 得到连接:
String connString = "jdbc:sqlite:d:test.db"; Connection conn = DriverManager.getConnection(connString);
- 得到 Statement对象
stmt = con.createStatement();
- 执行非查询:
stmt.executeUpdate("delete from TestTable");
- 查询得到数据集:
rs = stmt.executeQuery("SELECT * from DemoTable ORDER BY id");
- 加载驱动程序
- 概念:
设计模式:
- 分类:
- Creational Patterns
- Structural Patterns
- Behavioral Patterns
- GoF 原则:
- 单一职责原则
- 开放封闭原则
- 替换原则
- 依赖倒置原则: 高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不一定改依赖于实现细节,实现细节应该依赖于抽象
- 接口隔离原则: 客户端不应该依赖它不需要的接口; 一个类对另一个类的依赖应该建立在最小的接口上
- GRASP 原则; General Responsibility Assignment Software Pattern
- Information Expert (信息专家)
- Creator (创造者)
- Low Coupling (低耦合)
- High Cohesion (高内聚)
- Controller (控制器)
- Polymorphism (多态)
- Pure Fabrication (纯虚构)
- Indirection (间接)
- Protected Variations (受保护变化)
- 常见:
- 工厂模式,抽象工厂模式: 隔离内部实现细节
- 适配器模式:把一个接口或是类变成另一种,是不兼容的接口兼容
- 组合模式 Composite: 一致性地对待组合对象和独立对象,让使用者把单独的对象和组合对象混用
- 装饰器模式 Decorator: 为类添加新功能,防止类继承带来的爆炸式增长,为一个对象动态的加上一系列动作,而不需要因为这些动作的不同而产生大量的继承类
- 观察者模式 Observer: 隔离事件的发布者和处理者
- 分类:
反射:
- 概念: reflection: 在运行状态中对于任何一个类都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任何一个方法和属性
- 在一些框架性的程序中,反射是相当重要的:eg: plugin
- 跟PHP反射一个样
- 常用类:
- java.lang.reflect.*:
- 用法:
- 得到Class对象的3种方法:
- 类名.class:
Class<?> clss = String.class;
- 对象.getClass()
String str = "abc"; Class<?> cls = str.getClass();
- Class.forName(类的全名)
Class<?> cls = Class.forName("java.lang.String");
- 类名.class:
- 动态创建对象,调用相关方法
- 得到Class对象的3种方法:
- Annotation 注记:添加一些信息,在编译中或者在框架中使用
- 自定义注记:
- 定义:
- 使用 @interface 来定义一个类型,表示它是一个注记
- 使用 方法名() 来表示它的一个属性 (值或数组), 其中 value() 是默认属性,default 表示默认值
- 定义:
- 自定义注记:
- 概念: reflection: 在运行状态中对于任何一个类都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任何一个方法和属性
以下都是正确的说法
- 父类的非私有方法可以被子类自动继承。
- 字段变量可以自动赋初值。
- 多态是指一个程序中相同的名字表示不同的含义的情况。
- 系统在回收垃圾时会自动调用对象的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功能
- JComponent组件都是Container
- 事件监听器是一些接口,其中含有一些方法
- 事件监听器是一些事件的接口, 接口中含有相关的方法, 这些方法带一个事件对象作为参数
以下都是错误的说法:
- 如果一个类被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对象。
- 错误 ????
- DataOutputStream可以以二进制的方式写入double。
- 错误 ????
- 所有的事件监听接口都可以用Lambda表达式。
- 错误 针对只有一个方法的接口,可以使用lambda表达式
- SQL中语句用双引号表示字符串
- 错误,用单引号
- 方法签名(signature)包括参数的类型及参数的名字。
- 错误。 包括一堆。。。。
- this和super是两个不同的对象
- 错误。 super是当前对象的父类,不是对象
- 如果一个类被abstract所修饰,说明这个类没有构造方法
- 错误: 抽象类的构造方法定义为protected,因为他只能被子类使用,即用super(paraments);
- 实例初始化,先于静态初始化执行
- 错误: 顺序: 父类静态初始化, 子类静态初始化,父类初始化,父类构造,子类初始化,子类构造
- 内部类中不能访问外部类的private字段及方法
- 错误: 可以的
- 若父类中的方法声明了throws异常,则子类Override时一定也要throws异常。
- 错误: 子类重写父类方法要抛出与父类一致的异常,或者不抛出异常。 子类重写父类方法所抛出的异常不能超过父类的范畴。
- Integer I = 5 实际表示Integer I = new Integer(5)。
- 错误: 1-127 是在integerCache里面的,不会new 一个Integer
- 后台线程(deamon)不会自动结束
- 错误: 守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则JVM不会退出
- JDBC中RecordSet表示结果集
- 错误: ResultSet表示结果集, RecordSet目测是VB的
- Java中的输入输出流的连接实际上使用了"装饰模式“。
- 错误:
实例初始化,先于静态初始化执行
各种缩写词
- POM: Project Object Model
- Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤
666 · 1
(点赞功能开发中)