一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中反射詳解

Java中反射詳解

2020-08-13 11:58風一樣的碼農 Java教程

本文主要介紹了Java中反射的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧

閱讀目錄

  1. Java反射API
  2. 通過反射創建實例對象
  3. 通過反射調用私有方法
  4. 關于javap工具
  5. 參考資料

Java反射API

Java反射指的是在運行狀態時,能夠獲取類的屬性和方法或者修改類運行時行為的過程。

java.lang.Class類提供了很多方法用于獲取元數據、檢查和改變類運行時的行為。

Java的反射主要涉及java.lang和java.lang.reflect包下的類。

反射應用場景舉例

  1. IDE, 如Eclipse、MyEclipse、NetBeans等;
  2. 調試器;
  3. 測試工具等;
  4. 各大框架、spring、hibernate等;

java.lang.Class類

java.lang.Class主要提供了以下兩個功能:

  1. 提供方法用于訪問運行期間類的元數據;
  2. 提供方法用于檢查和修改類的運行時行為;

java.lang.Class類常用方法

 

Method Description
1) public String getName() 返回類名
2) public static Class forName(String className)throws ClassNotFoundException 加載類并返回Class對象
3) public Object newInstance()throws InstantiationException,IllegalAccessException 創建實例對象
4) public boolean isInterface() 判斷是否是接口
5) public boolean isArray() 判斷是否是數組
6) public boolean isPrimitive() 判斷是否是原始數據類型
7) public Class getSuperclass() 返回父類Class引用
8) public Field[] getDeclaredFields()throws SecurityException 返回類的成員屬性字段數組
9) public Method[] getDeclaredMethods()throws SecurityException 返回類的方法數組
10) public Constructor[] getDeclaredConstructors()throws SecurityException 返回類的構造方法數組
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException 返回類中指定參數類型的方法

 

怎樣獲取Class對象

有三種方式,如下:

  1. Class類的forName()方法,動態加載,運行時,開始裝入類, 并做類的靜態初始化
  2. 對象的getClass()方法,靜態加載(編譯時已加載)
  3. .class語法, 靜態加載(編譯時已加載)

forName()方法示例

可用于動態加載,當你知道類的全限定名時,可以使用該方式。注意原始數據類型不適用該方法;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[]) throws ClassNotFoundException
 {
 Class<?> c = Class.forName("tmp.Simple");
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
?
1
2
tmp.Simple
Simple

getClass()方法示例:

從實例對象中獲取Class對象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package tmp;
class Simple
{
}
public class Test
{
 void printName(Object obj)
 {
 }
 public static void main(String args[])
 {
 Simple s = new Simple();
 Class<? extends Object> c = s.getClass();
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
?
1
2
tmp.Simple
Simple

.class語法示例

作用于類名上,也可應用于原始數據類型,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
package tmp;
public class Test
{
 public static void main(String args[])
 {
 Class<Boolean> c = boolean.class;
 System.out.println(c.getName());
 Class<Test> c2 = Test.class;
 System.out.println(c2.getName());
 }
}
?
1
2
boolean
tmp.Test

判斷Class對象對應的類型

以下方法可用于判斷Class對象對應的類型:

 

1) public boolean isInterface(): 是否對應接口
2) public boolean isArray(): 是否對應數組
3) public boolean isPrimitive(): 是否對應原始數據類型

 

代碼示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package tmp;
class Simple
{
}
interface My
{
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 System.out.println(c.isInterface());
 Class<?> c2 = Class.forName("tmp.My");
 System.out.println(c2.isInterface());
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}
?
1
2
false
true

通過反射創建實例對象

有兩種方式,如下:

  1. 通過Class對象的newInstance()方法創建,這種方式只能調用無參構造方法;
  2. 通過Constructor對象的newInstance()方法創建,這種方式適用于有參構造方法,并且還可以破壞單例模式,調用私有構造方法;

所以,通常來講,第二種方式比第一種使用范圍更廣。

Class對象調用newInstance()方法示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package tmp;
class Simple
{
 void message()
 {
 System.out.println("Hello Java");
 }
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 Simple s = (Simple) c.newInstance();
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Hello Java

Constructor對象調用newInstance()方法示例

注意這里可以根據傳入參數的類型來得到指定的構造方法,還可以改變構造方法的訪問權限限制。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package tmp;
import java.lang.reflect.Constructor;
class Simple
{
 private String msg;
 void message()
 {
 System.out.println("Hello Java," + msg);
 }
 private Simple(String s){
 this.msg = s;
 }
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 Constructor<?> con = c.getDeclaredConstructor(String.class);
 con.setAccessible(true);
 Simple s = (Simple) con.newInstance("...");
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Hello Java,...

通過反射調用私有方法

通過反射,我們可以調用其它類的私有方法,主要涉及java.lang.Class和java.lang.reflect.Method類;

其中主要是用到了Method類的setAccessible方法和invoke方法,前者修改訪問權限,后者調用方法。

通過調用有參私有方法示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package tmp;
import java.lang.reflect.Method;
class A
{
 private void cube(int n)
 {
 System.out.println(n * n * n);
 }
}
class Test
{
 public static void main(String args[]) throws Exception
 {
 Class<A> c = A.class;
 Object obj = c.newInstance();
 Method m = c.getDeclaredMethod("cube", new Class[]{ int.class });
 m.setAccessible(true);
 m.invoke(obj, 4);
 }
}

關于javap工具

使用javap命令可以反匯編java的字節碼文件,展示class文件中的字段屬性、構造方法、普通方法信息;

使用說明:

Java中反射詳解

javap java.lang.Object示例

javap -c Test示例:

Java中反射詳解

寫個簡單的Test類,如下:

?
1
2
3
4
5
6
7
8
9
10
11
package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[])
 {
 System.out.println("Hello");
 }
}

輸入javap -c Test:

Java中反射詳解

參考資料

基本屬于翻譯,做了小部分修改

http://www.javatpoint.com/java-reflection

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

原文鏈接:http://www.cnblogs.com/chenpi/p/6409870.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩高清在线高清免费 | 经典千人斩一区二区视频 | 九九热精品免费观看 | 2018天天拍拍拍免费视频 | 亚洲国产精品一区二区三区久久 | dyav午夜片| brazzersvideo欧美最新 | 性欧美videofree中文字幕 | 丝瓜香蕉视频 | 免费标准高清看机机桶机机 | 欧美成人一区二区三区 | 午夜看片a福利在线观看 | 99视频在线免费观看 | 日本一区二区视频在线 | 视频在线观看一区二区三区 | 亚洲a视频在线 | 日本韩国无矿砖码 | 午夜理论电影在线观看亚洲 | 日韩在线一区二区三区免费视频 | 成人国产第一区在线观看 | chaopeng在线观看 | 国产在线视频资源 | 国产九九| 亚洲偷窥图区色 | 97影院伦理 | 国产精品片| 欧美xxoo黑人又粗暴 | 欧美视频网址 | 无码AV免费精品一区二区三区 | 91麻豆国产福利在线观看 | 都市后宫小说 | 门房秦大爷在线阅读 | a看片| 亚洲AV无码乱码国产麻豆穿越 | 小草观看免费高清视频 | 成人影院www在线观看 | 好姑娘在线视频观看免费 | 蜜臀91| 国产日韩片 | 日韩毛片在线视频 | 日本精工厂网址 |