Java之隐秘的角落
概况
主要说下工作中经常见到,但是不经常使用的一些小知识
断点调试
基础使用
运行到下一行
进入自定义方法(就是你自己写的方法)
跳出方法
查看所有的断点
让断点失效
跳出jdk中定义的方法,与3类似
进入jdk中定义的方法,与2类似
综合了2和7
跳出当前执行的方法,例如:打断点进入这个方法,大眼一看就不是这个方法的问题,就可以用这个
针对自定义代码,不需要打断点,光标放在哪一行,就跳转的哪一行,前提是能执行到你的光标位置
针对jdk代码,不需要打断点,光标放在哪一行,就跳转的哪一行,前提是能执行到你的光标位置
跳转到正在执行的那一行,你打断点的时候,已经执行了几行,手动点击了很多方法,这个可以一下回到代码正在执行的位置
值就算器,可以计算当前内存中的值
我也不知道
强制返回,有时候好不容易造一条数据,代码一执行,数据就要重新造,只能停止项目,再重启,就可以用这个方法
同15,不过是抛异常的形式
条件断点
如图,我想让它在i=500
的时候执行断点
接口
在jdk8
之前,接口中只能定义抽象方法
在jdk8
中,接口可以直接声明静态方法,普通方法(使用default
关键字修饰)
在jdk9
中,接口可以声明为私有方法,供默认方法调用
public interface InterfaceA {
//jdk1.8之前义抽象方法
void showA();
//jdk1.8定义静态方法
static void showA(){
System.out.println("定义静态方法");
}
//jdk1.8定义普通方法
default void showB(){
System.out.println("定义普通方法");
}
//jdk9中定义普通方法
private String showC(){
return "定义了私有方法";
}
//jdk9中使用普通方法
default String showD(){
return showC();
}
}
注意点:
接口中的静态方法只能接口直接调用,实现类不能调用
当一个实现类实现多个接口时,接口中都含有同名,同参数的默认方法,实现类需要重写默认方法
当一个实现类的父类和接口空都有同名,同参数的方法,自己未实现该方法,以父类的方法为主(类的优先原则)
子类调用自己中的方法
method()
,调用父类中的方法super.method()
,调用接口中的默认方法InterfaceA.super.method()
运算符>>
和>>>
在源码中经常见到位运算符
,例如在HashMap
的源码中有如下表述
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
那具体代表什么呢?详细内容见 运算符>>和>>>有什么区别以及原码、反码、补码
>>
表示右移,如果该数为正,则高位补0,若为负数,则高位补1。如:int i=15; i>>2的结果是3,移出的部分将被抛弃。
转为二进制的形式可能更好理解,0000 1111(15)右移2位的结果是0000 0011(3),0001 1010(18)右移3位的结果是0000 0011(3)。
>>>
表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。其他结构和>>相似。
transient关键字
java中的transient关键字,transient是短暂的意思。
对于transient 修饰的成员变量,在类的实例对象的序列化处理过程中会被忽略。 因此,transient变量不会贯穿对象的序列化和反序列化,生命周期仅存于调用者的内存中而不会写到磁盘里进行持久化。
补充知识点
基础数据类型默认为是序列化的,自定义引用数据类型网络传输过程中需要手动序列化
静态(static)变量的值不会序列化。因为静态变量的值不属于某个对象。
transient修饰的变量不会序列化