20201209——java反射
靜態與動態
動態語言 java c c++
靜態語言 python javascript
就看是否能在執行的時候,是否可以改變其結構
Reflection
反射,是java被視為動態語言的關鍵,反射機制允許程式在執行期藉助於Reflection API取得任何類的內部資訊,並且能直接操作任意物件的內部屬性及方法。
載入完一個類之後,在堆記憶體的方法區就產生了一個Class型別的物件(一個類只能有一個Class物件),這個物件完整的包含了完整的類的結構資訊,我們可以通過這個物件看到類的結構,這個物件就像一面鏡子,透過這個鏡子我們就可以看到類的結構,所以我們形象的稱之為反射
提供的功能應用
在執行時判斷任意一個物件所屬的類
在執行時構造任意一個類的物件
在執行時判斷任意一個類所具有的成員變數和方法
在執行時獲取泛型資訊
在執行時呼叫任意一個物件的成員變數和方法
在執行時處理註解
生成動態代理
反射的優缺點
優點
可以實現動態建立物件和編譯,體現出很大的靈活性
缺點
對效能有影響,使用反射基本上是一種解釋操作,我們可以告訴jvm,我們希望做什麼並且滿足它的要求,這類操作總是慢於直接執行相同的操作。
反射主要相關的API
java.lang.Class 類
java.lang.reflect.Method 類的方法
java.lang.reflect.Field 類的成員變數
java.lang.reflect.Constructor 類的構造器
獲取反射物件
一個類只有一個class物件
/**
* @Classname TestReflection
* @Description TODO
* @Date 2020/12/9 10:57
* @Created by mmz
*/
public class TestReflection {
// 反射獲取類的class物件
public static void main(String[] args) throws ClassNotFoundException {
Class user = Class.forName("User");
System.out.println(user);
Class user1 = Class.forName("User");
Class user2 = Class.forName("User");
System.out.println(user1 == user2);
}
}
// 實體類 pojo Entity
class User{
private String name;
private int id;
private int age;
public User(){
}
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
因為最後結果返回的是,user1 == user2 為true
Class類
物件照鏡子的最後可以得到的資訊:某個類的屬性,方法和構造器,某個類到底實現了哪些介面。
對於每個類而言,JRE都為其保留一個不變的Class型別的物件,一個Class物件包含了特定某個結構的有關資訊
class本身也是一個類
class物件只能由系統建立物件
一個載入的類在jvm中只會有一個class例項
一個class物件對應是一個載入到jvmz紅的一個.class檔案
每個類的例項都會記得自己是由哪個Class例項所生成
通過Class可以完整地得到一個類中所有的被載入的結構
Class類是Reflection的根源,針對於任何你想動態載入,執行的類,唯有先獲得相應的Class物件
Class類的常用方法
獲取class類的例項
1)若已經知道具體的類,通過類的class屬性獲取,該方法最為安全可靠,程式效能最高
Class class = Person.class
2)已知某個類的例項,呼叫該例項的getClass()方法獲取class物件
Class class = person.getClass()
3)已知一個類的全類名,且該類在類路徑下面,可通過Class類的靜態方法forName()獲取,可能丟擲ClassNotFoundException
Class class = CLass.forName("java.lang.String")
4)內建基本資料型別可以直接用類名.Type
5)還可以利用ClassLoader
/**
* @Classname TestCreate
* @Description TODO
* @Date 2020/12/9 14:19
* @Created by mmz
*/
/*測試class類的建立方式有幾種*/
public class TestCreate {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("這個人是" + person.name);
// 方式一:通過物件獲得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
// 方式二:通過forName獲得
Class c2 = Class.forName("Student");
System.out.println(c2.hashCode());
// 方式三:通過類獲得
Class c3 = Student.class;
System.out.println(c3.hashCode());
// 方式四:基本內建型別的包裝類都有一個Type屬性
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4);
// 獲得父類型別
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
String name;
public Person(String name) {
this.name = name;
}
public Person(){
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person{
public Student(){
this.name = "學生";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "老師";
}
}
相關文章
- java反射——反射AnnotationJava反射
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java 反射Java反射
- Java——反射Java反射
- Java反射Java反射
- 20201209——java記憶體分析Java記憶體
- Java反射—初探反射基礎Java反射
- Java反射與反射優化Java反射優化
- Java 反射原理Java反射
- Java反射-模組Java反射
- Java的反射Java反射
- java反射——FieldJava反射
- Java之反射Java反射
- java反射(2)Java反射
- java反射示例Java反射
- Java 反射 APIJava反射API
- 淺析Java反射--JavaJava反射
- 【Java面試指北】反射(1) 初識反射Java面試反射
- Java筆記-Java反射(二)Java筆記反射
- Java基礎系列—Java反射Java反射
- java反射詳解Java反射
- Java 反射簡介Java反射
- java反射全解Java反射
- Java 反射基礎Java反射
- 淺析JAVA反射Java反射
- Java 反射詳解Java反射
- 秒懂Java反射Java反射
- Java反射-屬性Java反射
- Java反射-註解Java反射
- Java學習:反射Java反射
- Java學習_反射Java反射
- Java筆記-反射Java筆記反射
- Java 方法的反射Java反射
- JAVA反射舉例Java反射
- 初識Java反射Java反射
- java註解,反射Java反射
- java基礎——反射Java反射