、一、前言
之前定义枚举类enum,基于形式基于枚举类的定义构成函数,枚举项本身根据枚举类定义的属性进行实例化,如下所示,通过阅读java.util.concurrent.TimeUnit,可以基于公共的静态属性,对每一个枚举项基于公共静态属性重新各自的方法,具体参考源码说明部分。
public enum TimeUnit {@b@ @b@ sec(60,"秒"),@b@ min(60,"分"),@b@ hour(24,"时");@b@ @b@ private Integer code;@b@ private String desc;@b@@b@ private TimeUnit(Integer code, String desc) {@b@ this.code = code;@b@ this.desc = desc;@b@ }@b@ @b@ public Integer getCode() {@b@ return code;@b@ }@b@@b@ public void setCode(Integer code) {@b@ this.code = code;@b@ }@b@@b@ public String getDesc() {@b@ return desc;@b@ }@b@@b@ public void setDesc(String desc) {@b@ this.desc = desc;@b@ }@b@}
二、源码说明
对于枚举类TimeUnit定义了C0-C6静态长整型属性,对于成员方法toNanos、toMicros、toMillis、toSeconds、toMinutes、toHours、toDays、convert、excessNanos都是空实现体方法,枚举项NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS、MINUTES、HOURS、DAYS分别根据时他们自身差异性基于静态C0-C6这些基本属性进行组合转换实现TimeUnit他们这些具体空方法体
package java.util.concurrent;@b@ @b@public enum TimeUnit {@b@ NANOSECONDS {@b@ public long toNanos(long d) { return d; }@b@ public long toMicros(long d) { return d/(C1/C0); }@b@ public long toMillis(long d) { return d/(C2/C0); }@b@ public long toSeconds(long d) { return d/(C3/C0); }@b@ public long toMinutes(long d) { return d/(C4/C0); }@b@ public long toHours(long d) { return d/(C5/C0); }@b@ public long toDays(long d) { return d/(C6/C0); }@b@ public long convert(long d, TimeUnit u) { return u.toNanos(d); }@b@ int excessNanos(long d, long m) { return (int)(d - (m*C2)); }@b@ },@b@ MICROSECONDS {@b@ public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }@b@ public long toMicros(long d) { return d; }@b@ public long toMillis(long d) { return d/(C2/C1); }@b@ public long toSeconds(long d) { return d/(C3/C1); }@b@ public long toMinutes(long d) { return d/(C4/C1); }@b@ public long toHours(long d) { return d/(C5/C1); }@b@ public long toDays(long d) { return d/(C6/C1); }@b@ public long convert(long d, TimeUnit u) { return u.toMicros(d); }@b@ int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }@b@ },@b@ MILLISECONDS {@b@ public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }@b@ public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }@b@ public long toMillis(long d) { return d; }@b@ public long toSeconds(long d) { return d/(C3/C2); }@b@ public long toMinutes(long d) { return d/(C4/C2); }@b@ public long toHours(long d) { return d/(C5/C2); }@b@ public long toDays(long d) { return d/(C6/C2); }@b@ public long convert(long d, TimeUnit u) { return u.toMillis(d); }@b@ int excessNanos(long d, long m) { return 0; }@b@ },@b@ SECONDS {@b@ public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }@b@ public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }@b@ public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }@b@ public long toSeconds(long d) { return d; }@b@ public long toMinutes(long d) { return d/(C4/C3); }@b@ public long toHours(long d) { return d/(C5/C3); }@b@ public long toDays(long d) { return d/(C6/C3); }@b@ public long convert(long d, TimeUnit u) { return u.toSeconds(d); }@b@ int excessNanos(long d, long m) { return 0; }@b@ },@b@ MINUTES {@b@ public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }@b@ public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }@b@ public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }@b@ public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }@b@ public long toMinutes(long d) { return d; }@b@ public long toHours(long d) { return d/(C5/C4); }@b@ public long toDays(long d) { return d/(C6/C4); }@b@ public long convert(long d, TimeUnit u) { return u.toMinutes(d); }@b@ int excessNanos(long d, long m) { return 0; }@b@ },@b@ HOURS {@b@ public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }@b@ public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }@b@ public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }@b@ public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }@b@ public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }@b@ public long toHours(long d) { return d; }@b@ public long toDays(long d) { return d/(C6/C5); }@b@ public long convert(long d, TimeUnit u) { return u.toHours(d); }@b@ int excessNanos(long d, long m) { return 0; }@b@ },@b@ DAYS {@b@ public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }@b@ public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }@b@ public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }@b@ public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }@b@ public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }@b@ public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }@b@ public long toDays(long d) { return d; }@b@ public long convert(long d, TimeUnit u) { return u.toDays(d); }@b@ int excessNanos(long d, long m) { return 0; }@b@ };@b@@b@ // Handy constants for conversion methods@b@ static final long C0 = 1L;@b@ static final long C1 = C0 * 1000L;@b@ static final long C2 = C1 * 1000L;@b@ static final long C3 = C2 * 1000L;@b@ static final long C4 = C3 * 60L;@b@ static final long C5 = C4 * 60L;@b@ static final long C6 = C5 * 24L;@b@@b@ static final long MAX = Long.MAX_VALUE;@b@ @b@ static long x(long d, long m, long over) {@b@ if (d > over) return Long.MAX_VALUE;@b@ if (d < -over) return Long.MIN_VALUE;@b@ return d * m;@b@ }@b@@b@ @b@ public long convert(long sourceDuration, TimeUnit sourceUnit) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toNanos(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toMicros(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toMillis(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toSeconds(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toMinutes(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toHours(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ public long toDays(long duration) {@b@ throw new AbstractMethodError();@b@ }@b@@b@ @b@ abstract int excessNanos(long d, long m);@b@@b@ @b@ public void timedWait(Object obj, long timeout)@b@ throws InterruptedException {@b@ if (timeout > 0) {@b@ long ms = toMillis(timeout);@b@ int ns = excessNanos(timeout, ms);@b@ obj.wait(ms, ns);@b@ }@b@ }@b@@b@ @b@ public void timedJoin(Thread thread, long timeout)@b@ throws InterruptedException {@b@ if (timeout > 0) {@b@ long ms = toMillis(timeout);@b@ int ns = excessNanos(timeout, ms);@b@ thread.join(ms, ns);@b@ }@b@ }@b@@b@ @b@ public void sleep(long timeout) throws InterruptedException {@b@ if (timeout > 0) {@b@ long ms = toMillis(timeout);@b@ int ns = excessNanos(timeout, ms);@b@ Thread.sleep(ms, ns);@b@ }@b@ }@b@@b@}