具有内部类构造函数参数的Java Reflection奇数
關于Java內部類
Java允許成員類(在其他類內定義的類),局部類(在語句塊內定義的類)和匿名類(無名稱的類):
Java語言規范將成員,本地和匿名類分類為內部類 。
實施“細節”
Java語言或虛擬機規范沒有告訴您的是它們是如何實現的。 其他文章已經對此進行了解釋,例如Java編譯器如何生成綜合方法以允許這些成員類訪問私有字段,而JVM不允許這樣做。
易于理解的內部類的另一個實現細節是內部類的構造函數采用額外的綜合參數。 相對眾所周知 ,內部類構造函數的第一個綜合參數將是其封閉實例,并將其存儲在this$X綜合字段中。 這對所有三種內部類均有效:成員,本地和匿名。
但是通常不知道捕獲非恒定最終變量的本地類是否要求將所有這些變量作為額外的綜合構造函數參數傳遞(捕獲的常數最終變量將被內聯并且不會生成額外的綜合構造函數參數):
class Outer {void method() {final String constant = "foo";final String nonConstant = "foo".toUpperCase();class Local{/* synthetic fields and constructor:Outer this$0;String nonConstant;Local(Outer this$0, String nonConstant){this.this$0 = this$0;this.nonConstant = nonConstant;}*/}Local l = new Local();} }好的,但是我為什么要關心呢?
在大多數情況下,除了您自己的好奇心之外,您根本不在乎。 但是,如果您正在使用內部類進行Java反射,那么您應該了解一些事情,并且由于我還沒有在線找到或列出它們,所以我認為列出一系列可以幫助他人理解的事情很重要。因為不同的編譯器將在Java Reflection API中產生不同的結果。
問題是當您使用Java反射為內部類構造函數獲取java.lang.reflect.Constructor實例時會發生什么? 特別是,允許??您訪問參數類型(前泛型: getParameterTypes() ),通用參數類型(后泛型: getGenericParameterTypes() )和注釋( getParameterAnnotations() )以及答案的方法會發生什么?是: 這取決于 。
假設以下Java類:
class Outer {class Inner {Inner(){}Inner(String param){}Inner(@Deprecated Integer param){}} }這是我們的每個構造函數上這三種反射方法返回的數組的大小,以及它們根據所使用的Java編譯器的不同而有所不同:
| getParameterTypes() 。長度 | 1個 | 2 | 2 |
| getGenericParameterTypes() .length用Eclipse編譯 | 1個 | 2 | 2 |
| getGenericParameterTypes() .length用Javac編譯 | 0 | 1個 | 1個 |
| getParameterAnnotations() 。長度 | 1個 | 2 | 1個 |
如您所見,合成參數始終包含在getParameterTypes() ,但僅在使用Eclipse進行編譯時才包含在getGenericParameterTypes() 。
另一方面, getParameterAnnotations()將始終包含合成參數,除非注釋了至少一個構造函數參數。
通過此信息,您現在了解了這些方法的結果之間的差異,但是到目前為止,我仍然沒有找到確定哪個參數是合成參數的方法,因為盡管您可以對this$X合成做出很好的猜測參數,這是每個內部類都需要的,因此您無法知道將捕獲為局部類構造函數的綜合參數的非常量捕獲變量的數量。
參考: Ceylon Team博客博客中的JCG合作伙伴 Stef Epardaud提供了帶有內部類構造函數參數的Java反射奇數。翻譯自: https://www.javacodegeeks.com/2013/05/java-reflection-oddities-with-inner-class-constructor-parameters.html
總結
以上是生活随笔為你收集整理的具有内部类构造函数参数的Java Reflection奇数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 潍坊房产网上备案查询官网(潍坊房产网上备
- 下一篇: 安卓平板电脑(安卓手机平板)