继续我的复习刷题
构造器显式调用父类构造方法的规则
题目:
以下程序的输出结果为
class Base{
public Base(String s){
System.out.print("B");
}
}
public class Derived extends Base{
public Derived (String s) {
System.out.print("D");
}
public static void main(String[] args){
new Derived("C");
}
}
A. BD
B. DB
C. C
D. 编译错误
正确答案: D 你的答案: A (错误)
这道题其实没什么特别的,就是之前对这个规则不熟悉:
在子类的构造方法中,必须调用父类的构造方法,如果没有显示地调用,编译器会在第一行添加一个父类的无参构造方法,但是如果父类重载了构造方法导致没有无参的构造方法,子类就必须在构造方法中显示地调用父类的构造方法,否则就会报错。
IO流分为节点流和处理流
题目:
下列流当中,属于处理流的是:()
A. FileInputStream
B. InputStream
C. DataInputStream
D. BufferedInputStream
正确答案: C D 你的答案: A C (错误)
这道题选错是不知道节点流和处理流是什么。原来IO流可以这样分类:(来自牛客网用户:无情的AC机器)
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
- 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader.
- 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
JAVA常用的节点流:
+ 文 件 FileInputStream
、FileOutputStrean
、FileReader
、FileWriter
。文件进行处理的节点流。
+ 字符串 StringReader
、StringWriter
。对字符串进行处理的节点流。
+ 数 组:ByteArrayInputStream
、ByteArrayOutputStreamCharArrayReader
、CharArrayWriter
。对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
+ 管 道:PipedInputStream
、PipedOutputStream
、PipedReaderPipedWriter
。对管道进行处理的节点流。
常用处理流(关闭处理流使用关闭里面的节点流)
- 缓冲流:
BufferedInputStream
、BufferedOutputStream
、BufferedReader
、BufferedWriter
。增加缓冲功能,避免频繁读写硬盘。 - 转换流:
InputStreamReader
、OutputStreamReader
。实现字节流和字符流之间的转换。 - 数据流:
DataInputStream
、DataOutputStream
等。提供将基础数据类型写入到文件中,或者读取出来.
如何通过反射获取和设置对象私有字段的值
这个倒不是刷题刷出来的,就是整理知识点的时候对这个API有点不太熟练,这里复习一下:

我相信这个思维导图已经概括得很详细了(这只是我复习中整理的一小部分,等我把整个java体系复习完了把整个思维导图分享出来)
下面上代码说明:
class Security{
private int num = 10;
private int getNum(){
return num;
}
}
public class TestReflect {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Security security = new Security();
// 获取字段
Field num = security.getClass().getDeclaredField("num");
// 设置访问权限
num.setAccessible(true);
// 修改值
num.set(security, 5);
Method getNum = security.getClass().getDeclaredMethod("getNum");
getNum.setAccessible(true);
Object invoke = getNum.invoke(security);
System.out.println(invoke);
}
}
这段代码中还有一个知识点:getNum
方法返回的是基本类型int,但invoke只能返回一个Object对象,它会自动把int类型装箱,即变成Integer类型返回,因此是可以输出的。
哈夫曼树&哈夫曼编码
哈哈越扯越偏了,这里顺便放一个数据结构的知识点上来,这个不太想单独写一篇博客。
哈夫曼树,就是使带权外部路径长度最小(课本上这样说的)的一种二叉树。
至于如何计算这个带权外部路径:
- 所有外部节点(叶子节点)带有一个权值
- 每个外部节点乘以其到根节点的路径长之和,就是该树的带权外部路径长度。
如何构造一个哈夫曼树:
- 将所有外部节点按权值大小从小到大排序,组成一个有序链表
- 取出前两个节点,将它们的值相加,得到一个新的权值,用它构造一个新的节点,同时是这两个节点的父节点,然后把这个新的节点按值的大小插入链表中
- 重复第二步,直到组成一棵树
我不太想画图,累了0v0(复习哪有时间认真写博客)
注意哈夫曼树是一种满二叉树(满二叉树这个定义有争议,我这里的定义就是除了叶子节点所有的节点的度都为2),即不包含度为1的节点。
然后哈夫曼树有一个应用就是哈夫曼编码,左边的出度取0,右边的出度取1。从根节点到叶子节点路径上的0、1值组成的就是哈夫曼编码。
原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/java%e5%9f%ba%e7%a1%80%e6%9f%a5%e7%bc%ba%e8%a1%a5%e6%bc%8f03%ef%bc%88%e9%99%84%e8%b5%a0%e5%93%88%e5%a4%ab%e6%9b%bc%e6%a0%91%e5%93%88%e5%a4%ab%e6%9b%bc%e7%bc%96%e7%a0%81%ef%bc%89/