java 反射 内存_Java 反射
Java 反射
正常的類加載過程
當執行new xxx();語句時,JVM會被觸發加載.class文件
JVM從本地文件找到class文件并且加載到內存中
JVM自動創建一個class對象 (一個類只產生一個class對象)
將Java的二進制代碼合并到JVM的運行狀態之中
驗證: 確保類的信息符合JVM規范,沒有安全問題
準備: 正式為類變量分配內存并設置默認初始值(都在方法區進行分配)
解析: 虛擬機常量池內的符號引用(常量名)替換為直接引用(地址)的過程
初始化
JAVA內存分析
堆
存放new的對象和數組
可以被所有的線程共享,不會存放別的對象引用
棧
存放基本變量類型
引用對象的變量
方法區
可以被所有的線程共享
包含了所有的class和static變量
類加載
PS: 這里僅僅是大概、其中省略了某些步驟
加載
將類中的靜態變量、方法等重新構建成一個新的數據結構
生成Class對象
驗證
分配內存
為類變量分配內存,設置初始值,在方法區中進行分配
解析
將變量替換成直接引用
初始化
執行 方法:編譯器按照順序,依次收集類變量的賦值語句以及static塊中的語句整合產生
public class Test04 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A {
static {
System.out.println("A -- static");
m = 100;
}
static int m = 200;
public A() {
System.out.println("A -- construct");
}
}
// A -- static
// A -- construct
// 200
public class Test04 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A {
static int m = 200;
static {
System.out.println("A -- static");
m = 100;
}
public A() {
System.out.println("A -- construct");
}
}
// A -- static
// A -- construct
// 100
優缺點
優點:
在運行時獲得類的各種內容,進行反編譯,代碼可以在運行時裝配
缺點:
消耗資源
安全問題
反射本質
得到class對象,反向獲取實體對象的各種信息
反射機制
將類的各個組成部分封裝成其他對象
優點
可以在程序運行過程中操作這些對象、
解耦
獲取Class對象的方式
Class.forName("全類名");// 將字節碼文件加載到內存,返回Class對象多用于配置文件
類名.class // 通過類名屬性class獲取 多用于參數傳遞
對象.getClass() // Object中定義了方法 多用于對象的獲取字節碼方式
package reflection;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import java.security.PublicKey;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student(); // 所對應的Class是Person而非Student
Student student = new Student();
Teacher teacher = new Teacher();
System.out.println("This is " + person.name);
// 通過對象獲得
Class c1 = person.getClass();
// forname
Class c2 = Class.forName("reflection.Student");
// 通過類名.class
Class c3 = Student.class;
// 基本內置類型的包裝類有一個Type屬性
Class c4 = Integer.TYPE;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
// 獲取父類類型
Class c5 = c1.getSuperclass();
System.out.println(c5);
Class c6 = teacher.getClass();
Class c7 = student.getClass();
System.out.println("teacher " + c6);
System.out.println("teacher hash " + c6.hashCode());
System.out.println("teacher super hash " + c6.getSuperclass().hashCode());
System.out.println("student hash " + c7.hashCode());
System.out.println("student super hash " + c7.getSuperclass().hashCode());
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person {
public Student() {
this.name = "Student";
}
}
class Teacher extends Person {
public Teacher() {
this.name = "Teacher";
}
}
使用Class對象
獲取屬性
獲取成員變量
獲取構造方法
public Constructor>[] getConstructors()// 獲取所有的Public構造方法
public Constructor>[] getDeclaredConstructors()// 獲取所有的構造方法(所 有 !)
public Constructor getConstructor(Class>... parameterTypes)//獲取單個共有的構造方法
public Constructor getDeclaredConstructor(Class... parameterTypes)//獲取某個構造方法(任意)
獲取成員方法
獲取類名
用反射機制創建實例
用Class對象的newInstance
Class c = String.class;
Object str = c.newInstance();
str += "123456";
System.out.println(str);
獲取Constructor,通過Constructor創建實例
// Person.java(Person類)
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 創建實例 Test.java (主類)
// 獲取Class對象
Class> p = Person.class;
// 通過獲取的Class對象獲取Constructor對象 (其中里面依次填入的是參數類型)
Constructor> constructor = p.getConstructor(String.class, int.class);
// 根據Constructor創建實例
Object person = constructor.newInstance("szx", 19);
System.out.println(person);
總結
以上是生活随笔為你收集整理的java 反射 内存_Java 反射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cad连接不同线段的端点_CAD绘图中两
- 下一篇: 样机模型尺寸怎么改_土耳其五代机全尺寸样