文章目录
java小细节
- 从java7开始加上前缀
0b
可以写二进制数 - 从java7开始数字可以用
1_000_000
表示,为了方便人阅读 - 没有后缀的浮点数默认是
double
类型 - 十六进制表示法中
p
表示指数,指数的基数是2
\u
转义字符需要注意
声明变量
- 对大小写敏感
>>>
会用0
填充高位,>>
会用符号位填充高位,不存在<<<
final
-
定义常量
-
不让继承子类
-
不允许子类重写方法
-
如果一个类被声明为
final
其方法自动为final
,而字段不会 -
< >
尖括号里面不能有基本类型 -
可以利用方法调用初始化一个字段
-
自动装箱的变量不适合用
==
进行比较,应该使用equals
接口
- 接口中的方法都自动为
public
,在实现类中要声明public
- 接口没有实例字段,接口字段总是
public static final
- 接口中可以有实现的方法,可以有静态方法
default
默认方法,更好的兼容性cloneable
是一个标记接口,不含有任何方法,只是起到一个标记的作用。允许使用instanceof
来检查
lambda表达式
- (String first, String second) -> first.length() - second.length();
- 如果可以推导出参数等类型,可以不用写
- 如果执行代码不止一行,可以使用
{}
来括起来 - 如果没有参数,使用空括号
方法引用
- Object::instanceMethod
- Class::instanceMethod
- Class::staticMethod
- 第一种情况,System.out.println,System.out是对象,调用System.out.println(x)
- 第二种情况,第一个参数会成为方法的隐式参数,例如String::compareToIgnoreCase,调用(x, y) -> x.compareToIgnoreCase(y);
- 第三种情况就是静态方法
- this::instanceMethod 与 super::instanceMethod一样可以使用
构造器引用
- Class::new
lambda表达式的三个部分
- 代码块
- 参数变量
- 自由变量,非参数值(表达式中不能改变自由变量的值,只是引用;外部自由变量的改变也是不行的)。lambda表达式可以访问代码块以外的变量。lambda捕获的变量必须是事实的最终变量。同样的,lambda表达式中的
this
变量是指调用表达式的这个类的
常用的函数接口
内部类
- 只有内部类才可以是私有的
- ==提醒:==剩下的不常用以后有时间再看看
代理
断言
日志
级别
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST
一般情况下,实际使用的是前三个级别
//获取日志记录器
private static final Logger myLogger = Logger.getLogger("com.mycompany.myapp");
//设置级别,现在FINE之前的都会被记录下来
//可以使用 Level.ALL Level.OFF打开和关闭所有
logger.setLevel(Level.FINE);
//记录方法
logger.warning(message);
logger.fine(message);
//也可以指定级别
logger.log(Level.FINE, message);
泛型
- 类型变量 放在修饰符的后面,返回类型的前面
public static <T> T method();
- 当调用一个方法的时候,可以把具体类型放在方法名前面
String s = Array.<String>getMethod("String");
方法限定
- 当需要一个包含一个方法compareTo的标准接口
public static <T extends Comparable> T min(T[] a);
extends
表示一个子类型的概念
- 一个类型变量或者通配符可以有多个限定
- 限定类型用
&
分隔,而,
用来分隔类型变量
- 限定类型用
- 最多可以限定一个类,且要放到最前面
类型擦除的问题
原始类型用第一个限定来替换类型变量,如果没有限定类型,就替换成
Object
- 由此可能会产生类型擦除与多态之间产生冲突,所以,编译器会产生一个桥方法
直观的讲, 带有超类型限定 的通配符允许你写入一个泛型对象,而带有子类型限定 的通配符允许你读取一个泛型对象
注意:
在java代码 中,根据参数类型的特征(签名)来判断一个方法,但在虚拟机 中会根据参数类型和返回值共同决定一个方法
- 在虚拟机中没有泛型,只有普通的类和方法
- 会合成桥方法来保持多态
- 所有方法类型都会替换成他们的限定类型
- 为了保持安全性,必要时会强制类型转换
局限性和限制
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型
- 不能创建参数化类型的数组
- 不能实例化类型变量
- 泛型类的静态上下文中类型变量无效
- 不能抛出或捕获泛型类的实例
无限定通配符
- 例如:
Pair<?>
与Pair
似乎一样,但Pair<?>
有以下方法:? getFirst()
void set First(?)
getFirst
只能赋值给一个Object
对象,setFirst
不能被调用
- 编译器必须能够保证通配符表示单个确定类型,例如:
ArrayList<Pair<T>>
中的T
永远不能捕获ArrayList<Pair<?>>
中的通配符
集合
- java的迭代器可以理解为:当调用
next
之后迭代器就越过下一个元素,并返回刚刚越过的元素引用。处于两个元素之间
-
collection
对于iterator
和Listinterator
有不一样的操作方法,后者更多一些,包括有
hasprevious
previous
这两个都是反向输出链表next/hasnext
iterator该有的它也有set(newValue)
这个用新值替代刚刚返回的值add(value)
这个在迭代器前添加一个元素
集,hashes/treeset
hashset
没有重复的元素,初始化可以设置桶的数目,也可以设置装填因子- 分别表示每个相同的散列值一共可以装多少
- 整个表中装填的百分比
treeset
平衡二叉树
队列
-
deque
双端队列ArrayDeque<Integer> integers = new ArrayDeque<>(); integers.offer(1); integers.offer(2); integers.offer(3); integers.offer(4); integers.offerLast(1); System.out.println(integers + integers.peekFirst().toString() +"\n"+ integers.pollLast() + integers);
-
优先队列
map集合、hashmap/treemap
- 与hashset/treeset类似
- map对键进行
hashcode
和放置,和值无关
- map对键进行