摘要:在學習的源碼過程中我遇到了一些有趣有用的方法,在此之前如果要使用這些工具方法,我首先會想到的是和這樣的語言擴展包,但現(xiàn)在如果是寫一些,使用原生即可達到目的。
在學習JDK的源碼過程中我遇到了一些有趣有用的方法,在此之前如果要使用這些工具方法,我首先會想到的是commons-lang和guava這樣的語言擴展包,但現(xiàn)在如果是寫一些demo,使用原生即可達到目的。當然我們也不能否認它們的作用,在平時的工作項目中幾乎都會引入這些語言擴展包,直接使用他們也使得編程風格統(tǒng)一,而且還能夠?qū)Φ桶姹镜腏DK提供支持。
以下收集的代碼片段可能會逐漸增加,也可能不會。
java.util.Objects工具類,我覺得好用的幾個方法
public static boolean equals(Object var0, Object var1) { return var0 == var1 || var0 != null && var0.equals(var1); } public static int hashCode(Object var0) { return var0 != null ? var0.hashCode() : 0; } public staticT requireNonNull(T var0) { if (var0 == null) { throw new NullPointerException(); } else { return var0; } } public static T requireNonNull(T var0, String var1) { if (var0 == null) { throw new NullPointerException(var1); } else { return var0; } }
除此之外還應該從Objects學習到編寫工具類的正確的規(guī)范,
定義為final class
只定義一個無參的構造函數(shù)且拋出斷言錯誤,防止被反射調(diào)用
工具方法都是靜態(tài)方法
靜態(tài)方法中只拋出unchecked異常
java.lang.System這個最早應該是在Hello World程序中見到的,推薦它的一個方法
/** * Returns the same hash code for the given object as * would be returned by the default method hashCode(), * whether or not the given object"s class overrides * hashCode(). * The hash code for the null reference is zero. * * @param x object for which the hashCode is to be calculated * @return the hashCode * @since JDK1.1 */ public static native int identityHashCode(Object x);
注釋寫得很明白了,不管一個對象實例的class有沒有覆蓋Object的hashCode方法,都能使用這個方法獲得hash值。
獲取泛型類的類型參數(shù)我們可以從以下代碼獲得提示,代碼來自HashMap,
/** * Returns x"s Class if it is of the form "class C implements * Comparable", else null. */ static Class> comparableClassFor(Object x) { if (x instanceof Comparable) { Class> c; Type[] ts, as; Type t; ParameterizedType p; if ((c = x.getClass()) == String.class) // bypass checks return c; if ((ts = c.getGenericInterfaces()) != null) { for (int i = 0; i < ts.length; ++i) { if (((t = ts[i]) instanceof ParameterizedType) && ((p = (ParameterizedType)t).getRawType() == Comparable.class) && (as = p.getActualTypeArguments()) != null && as.length == 1 && as[0] == c) // type arg is c return c; } } } return null; }
這里的邏輯是獲得類C,然后獲取它實現(xiàn)的接口Comparable
public class ParameterApp { public static void main(String[] args) { StringList list = new StringList(); Class> clazz = getTypeArgument(list); System.out.println(clazz.getName()); } static Class> getTypeArgument(Object x) { if (x instanceof Collection) { Class> c = x.getClass(); Type[] ts, as; Type t; ParameterizedType p; if ((ts = c.getGenericInterfaces()) != null) { for (int i = 0; i < ts.length; ++i) { if (((t = ts[i]) instanceof ParameterizedType) && ((as = ((ParameterizedType)t).getActualTypeArguments()) != null) && as.length == 1) // type arg is c return (Class>) as[0]; } } } return null; } static class StringList extends AbstractListsun.reflect.Reflectionimplements List { @Override public String get(int i) { return null; } @Override public int size() { return 0; } } }
這個工具類是和反射相關的,讓大家知道有這么一個方法
@CallerSensitive public static native Class> getCallerClass();
我第一次見到這個方法是在java.sql.DriverManager中的getConnection方法中見到的
@CallerSensitive public static Connection getConnection(String url, String user, String password) throws SQLException { java.util.Properties info = new java.util.Properties(); if (user != null) { info.put("user", user); } if (password != null) { info.put("password", password); } return (getConnection(url, info, Reflection.getCallerClass())); }
Reflection.getCallerClass()是一個native方法,返回的是Class>類型,在DriverManager中使用它的目的是為了獲得相應的ClassLoader,上面的代碼是在Java 8中見到的。其中在Java 7中為獲得ClassLoader,DriverManager就直接提供了native的方法
/* Returns the caller"s class loader, or null if none */ private static native ClassLoader getCallerClassLoader();
我們用一段代碼嘗試調(diào)用這個方法
public class CalleeApp { public void call() { Class> clazz = Reflection.getCallerClass(); System.out.println("Hello " + clazz); } }
public class CallerApp { public static void main(String[] args) { CalleeApp app = new CalleeApp(); Caller1 c1 = new Caller1(); c1.run(app); } static class Caller1 { void run(CalleeApp calleeApp) { if (calleeApp == null) { throw new IllegalArgumentException("callee can not be null"); } calleeApp.call(); } } }
執(zhí)行main方法會拋出異常
Exception in thread "main" java.lang.InternalError: CallerSensitive annotation expected at frame 1
這個錯誤信息說的是我們?nèi)鄙僭诤瘮?shù)調(diào)用棧開始位置添加CallerSensitive注解,觀察DriverManager的getConnection方法確實是有這么個注解的。
那如果給CalleeApp的call加上注解,那結果又會怎樣呢?
這個方法是來賣萌,它的本義在注釋是這樣子寫的,
/* ** This method is similar to the {@code wait} method of one * argument, but it allows finer control over the amount of time to * wait for a notification before giving up. The amount of real time, * measured in nanoseconds, is given by: *
*** 1000000*timeout+nanos*/
意思是提供精細化的時間衡量,nano可是納秒單位啊!!!
而它的實現(xiàn)卻是這樣的,
public final void wait(long timeout, int nanos) throws InterruptedException { if (timeout < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0) { timeout++; } wait(timeout); }
除了對傳入?yún)?shù)的數(shù)值范圍校驗外,對nano的使用緊緊是判斷這個變量是否大于0,是則給timeout加1,這只是增加了1毫秒的時間,并沒有體現(xiàn)出了精細化的地方。
附you-dont-need-serial
Reflection.getCallerClass()使用的問題
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69032.html
摘要:作為條件變量的的不僅可以認為內(nèi)嵌了一把鎖,還內(nèi)嵌了一個條件變量。操作條件變量的函數(shù)將當前線程在條件變量上阻塞,一般是為了等待其他線程的某件事情執(zhí)行完成。其它裝箱類其它裝箱類的代碼這里就不分析了。重點關注下各裝箱類的緩存范圍。 jdk源碼讀到現(xiàn)在這里,重要的集合類也讀了一部分了。集合類再往下讀的話,就要涉及到兩個方向。第一,是比較典型的但是不常用的數(shù)據(jù)結構,這部分我準備將數(shù)據(jù)結構復習、回...
摘要:意味著完全保持,意味著完全丟棄。卡比獸寫這篇博文的時間我本可以抓一百只,請看下面的漫畫。神經(jīng)網(wǎng)絡神經(jīng)網(wǎng)絡會以的概率判定輸入圖片中的卡比獸正在淋浴,以的概率判定卡比獸正在喝水,以的概率判定卡比獸正在遭遇襲擊。最終結果是卡比獸正在遭遇襲擊 我第一次學習 LSTM 的時候,它就吸引了我的眼球。事實證明 LSTM 是對神經(jīng)網(wǎng)絡的一個相當簡單的擴展,而且在最近幾年里深度學習所實現(xiàn)的驚人成就背后都有它們...
摘要:在這篇文章中,我將列出我最喜歡的快捷鍵,這些快捷鍵讓我更快的編寫代碼,也讓編碼變得更有趣,以下是個快捷鍵,分享給你。打開鍵盤快捷鍵或,搜索。在中,啟動性能是很重要的。逐個選擇文本可以通過快捷鍵右箭頭右箭頭和左箭頭左箭頭逐個選擇文本。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 注意:自己嘗試的時候,Mac(17, p...
閱讀 2321·2021-11-24 10:18
閱讀 3385·2021-09-22 15:35
閱讀 3340·2021-09-13 10:37
閱讀 3766·2021-09-06 15:14
閱讀 2071·2021-09-06 15:02
閱讀 2212·2021-09-02 15:11
閱讀 547·2019-08-30 15:53
閱讀 3075·2019-08-29 16:15