☀ 快速索引
关于valueOf 的小小雷区
关于Math类(关于"静态类"的误区)
关于Math类的常用变量和方法
关于java.util.Calendar日期类
静态的import
▇ 关于valueOf 的小小雷区
临摹别人的回溯算法时,本来就很有挫败感,一个雷区更是令我绝望了好久:
char c = '2';
int temp = Integer.valueOf(c);
temp会是2吗?很不幸,是50;
这里企图将字符(Character)转化成数字(Integer),使用valueOf进行解析;然而,Integer.valueOf()压根没有传入char类型参数的重载方法
(可怕的是不会报错,而是在内内部把’2’转化成ASCII的整型值)
正确的姿势是使用String型过渡一下:
int temp = Integer.valueOf(String.valueOf(c));
▇ 关于Math类(关于"静态类"的误区)
先说下误区:认为Math是个静态类,毕竟我们平时一直在使用Math的静态方法
查看源码,真相大白:
public final class Math {
// 构造函数
private Math() {}
// 静态变量
public static final double E = 2.718281828459045;
public static final double PI = 3.141592653589793;
// 静态方法
public static double sin(double a) {
return StrictMath.sin(a);
}
// ...
}
Math 并不是静态类 !仅仅是final而已 !
要弄清楚一点:静态变量和静态方法不依赖于对象,直接使用类名调用。这个特征和类是否是静态压根没有关系。
我们讲静态类,是指静态内部类,它与非静态内部类的区别是:非静态内部类是其外部类的一部分,不能直接构造(需要先构造外部类);而静态内部类可以绕过外部类直接构造:
public class OuterCls { // 外部类
class InnerCls{}; // 非静态内部类
static class StaticInnerCls{}; // 静态内部类
public static void main(String[] args) {
new InnerCls(); // 报错。依赖于外部类而存在
new OuterCls().new InnerCls(); // 正确
new StaticInnerCls(); // 正确。静态内部类不依赖于外部类,可独立存在
}
}
另外,我们还应该问问自己,Math类通过什么方式避免了被做出对象呢?
显然不是通过标记为abstract抽象类。
其实是将构造函数标记为private私有,所以无法创建Math实例
▇ 关于Math类的常用变量和方法
E,PI;
abs(),max(),min()不必多说;
round()四舍五入返回整型;
random返回 [ 0.0, 1.0) 的双精度浮点数,通常这样用:
int n = (int)(Math.random() * 5) // 随机取0,1,2,3,4五个值
还有:sin, cos, exp, pow, log, log10, sqrt
▇ 关于java.util.Calendar日期类
在此之前,先举几个利用Date类输出时间的例子:
Date today = new Date(); // new出一个Date对象
System.out.println(String.format("%tc", today)); // 格式化输出时传入这个实例化的对象
System.out.println(String.format("%tA,%<tB,%<td", new Date())); // 一个小技巧,"<"表示重复利用之前用过的参数
格式化说明:
%tc | 完整日期 |
%tr | 时分秒 |
%tA | 周 |
%tB | 月 |
%td | 日 |
在取得当前日期或时间时,就用Date;而对时间的操作,使用Calendar类
Calendar t = Calendar.getInstance(); // Calendar是抽象类,不能直接new(这里实际上是取得了一个具体子类的实例)
t.set(2020, 6, 21, 14, 30); // 设置时间(年 月 日 时 分)
t.set(Calendar.MONTH, 6); // 设置指定字段的时间
System.out.println(t.getTime()); // 返回完整时间
System.out.println(t.get(Calendar.HOUR)); // 返回指定字段的时间
t.add(Calendar.DATE, 30); // 增减时间(会进位)
t.roll(Calendar.DATE, 30); // 增减时间(不进位)
另外有一个比较典型的操作,精确修改时间 :
long day = t.getTimeInMillis(); // 以毫秒为单位返回时间值
day += 1000 * 60 * 60; // 修改时间(ms)
t.setTimeInMillis(day); // 根据(被修改后的)毫秒值设置时间
System.out.println(t.getTime());
注 :HOUR
与HOUR_OF_DAY
注意区分一下
DATE
与DAY_OF_MONTH
完全一样
▇ 静态的import
作用一看便知 :
import static java.lang.System.out;
import static java.lang.Math.*;
class Test {
public static void main(String[] args) {
out.println(sqrt(2.0));
out.println(tan(60));
}
}
不建议这么做。
一来可读性变差;
二来名称容易混淆(很多类都有名称为add的方法,此时调用add(),调用的究竟是谁的add?);