Java 反射機(jī)制
簡(jiǎn)介:
Java的反射(reflection)機(jī)制是指在程序的運(yùn)行狀態(tài)中,可以構(gòu)造任意一個(gè)類的對(duì)象,可以了解任意一個(gè)對(duì)象所屬的類,可以了解任意一個(gè)類的成員變量和方法,可以調(diào)用任意一個(gè)對(duì)象的屬性和方法。這種動(dòng)態(tài)獲取程序信息以及動(dòng)態(tài)調(diào)用對(duì)象的功能稱為Java語(yǔ)言的反射機(jī)制。反射被視為動(dòng)態(tài)語(yǔ)言的關(guān)鍵。


1、反射:通過(guò)對(duì)象反射出一個(gè)類
package com.example.java.javakuangstudy.Reflection;
/**
* 反射練習(xí)-->得到class類的幾種方式
*/
public class Text01 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("我這個(gè)人是:" + person.name);
//TODO 方式一:通過(guò)對(duì)象獲取
Class<? extends Person> c1 = person.getClass();
System.out.println(c1.hashCode());
//TODO 方式二:
Class<?> c2 = Class.forName("com.example.java.javakuangstudy.Reflection.Student");
System.out.println(c2.hashCode());
//TODO 方式三:通過(guò)類名.class獲取
Class<Student> c3 = Student.class;
System.out.println(c3.hashCode());
//TODO 方式四:基本內(nèi)置類型的包裝類都有一個(gè)type屬性
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4);
//TODO 獲取父類類型
Class<?> c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person {
public 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 = "學(xué)生";
}
}
class Teacher extends Person {
public Teacher() {
this.name = "老師";
}
}
結(jié)果
我這個(gè)人是:學(xué)生
834600351
834600351
834600351
intclass com.example.java.javakuangstudy.Reflection.Person
2、分析類的初始化

package com.example.java.javakuangstudy.Reflection;
/**
* 測(cè)試類什么時(shí)候會(huì)初始化
*/
public class Text02 {
static {
System.out.println("Main被加載");
}
public static void main(String[] args) throws ClassNotFoundException {
//TODO 通過(guò)new 主動(dòng)引用
//Son son = new Son();
//TODO 通過(guò)反射也會(huì)產(chǎn)生主動(dòng)引用
//Class.forName("com.example.java.javakuangstudy.Reflection.Son");
//TODO 不會(huì)產(chǎn)生類的引用的方法
//TODO 1、子類調(diào)用父類的靜態(tài)方法
//int b = Son.b;
//System.out.println(b);
// TODO 2、通過(guò)數(shù)組
//Son[] arr = new Son[5]; //只打印--- Main被加載 (父類子類都不加載)
//TODO 3、調(diào)用常量
System.out.println(Son.M);
}
}
class Father {
static int b = 2;
static {
System.out.println("父類被加載");
}
}
class Son extends Father {
static {
System.out.println("子類被加載");
m = 300;
}
static int m = 100;
static final int M = 1;
}
3、動(dòng)態(tài)的創(chuàng)建對(duì)象 通過(guò)反射
package com.example.java.javakuangstudy.Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 動(dòng)態(tài)的創(chuàng)建對(duì)象 通過(guò)反射
*/
@SuppressWarnings("all")
public class Text03 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//TODO 獲得class對(duì)象
Class c1 = Class.forName("com.example.java.javakuangstudy.Reflection.User");
//TODO 構(gòu)造一個(gè)對(duì)象
User user = (User) c1.newInstance(); //本質(zhì)是調(diào)用了類的無(wú)參構(gòu)造
System.out.println(user);
//TODO 通過(guò)構(gòu)造器創(chuàng)建對(duì)象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user1 = (User) constructor.newInstance("liulianglin", 24, 251314);
System.out.println(user1);
//TODO 通過(guò)反射調(diào)用普通方法
User user2 = (User) c1.newInstance();
//TODO 通過(guò)反射獲取一個(gè)方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//TODO invoke激活的意思 (對(duì)象,"方法的值")
setName.invoke(user2, "劉亮林");
System.out.println(user2.getName());
//TODO 通過(guò)反射操作方法
System.out.println("----------------------");
User user3 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//TODO 不能直接操作私有屬性,我們需要關(guān)閉程序的安全檢測(cè),將setAccessible(true) 可提高效率
name.setAccessible(true);
name.set(user3, "liulianglin");
System.out.println(user3.getName());
}
}
4、 練習(xí)反射操作注解
package com.example.java.javakuangstudy.Reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
* 練習(xí)反射操作注解
*/
@SuppressWarnings("all")
public class Text04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.example.java.javakuangstudy.Reflection.Student2");
//TODO 通過(guò)反射獲取全部注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation); //@com.example.java.javakuangstudy.Reflection.Tablekuang(value=db_student)
}
//TODO 獲得注解的value值
Tablekuang tablekuang = (Tablekuang) c1.getAnnotation(Tablekuang.class);
String value = tablekuang.value();
System.out.println(value); //db_student
//TODO 獲得類指定的注解
Field name = c1.getDeclaredField("id");
Fieldkuang annotation = name.getAnnotation(Fieldkuang.class);
System.out.println(annotation.columnName()); //db_id
System.out.println(annotation.type()); //int
System.out.println(annotation.length()); //18
}
}
@Tablekuang("db_student")
class Student2 {
@Fieldkuang(columnName = "db_id", type = "int", length = 18)
private int id;
@Fieldkuang(columnName = "db_age", type = "int", length = 18)
private int age;
@Fieldkuang(columnName = "db_name", type = "varchar", length = 18)
private String name;
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
//TODO 類名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tablekuang {
String value();
}
//TODO 屬性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldkuang {
String columnName();
String type();
int length();
}
到此這篇關(guān)于Java 反射機(jī)制的文章就介紹到這了,更多相關(guān)Java反射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案
相信大家在使用idea的時(shí)候一定會(huì)遇到這樣的問(wèn)題,就是在service里注入mapper的時(shí)候,明明代碼沒(méi)有問(wèn)題,也可以運(yùn)行,但是idea它就是給你報(bào)個(gè)錯(cuò),有個(gè)紅色的波浪線在下面,所以本文將給大家介紹了idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案,需要的朋友可以參考下2023-12-12
Java通過(guò)wait()和notifyAll()方法實(shí)現(xiàn)線程間通信
這篇文章主要為大家詳細(xì)介紹了Java通過(guò)wait()和notifyAll()方法實(shí)現(xiàn)線程間通信的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
SpringBoot+RabbitMQ方式收發(fā)消息的實(shí)現(xiàn)示例
這篇文章主要介紹了SpringBoot+RabbitMQ方式收發(fā)消息的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Springboot+Vue+axios實(shí)現(xiàn)文章收藏功能
這篇文章主要為大家詳細(xì)介紹了Springboot+Vue+axios實(shí)現(xiàn)文章收藏功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Mybatis調(diào)用存儲(chǔ)過(guò)程的案例
這篇文章主要介紹了Mybatis如何調(diào)用存儲(chǔ)過(guò)程,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
Java?離線中文語(yǔ)音文字識(shí)別功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java?離線中文語(yǔ)音文字識(shí)別,本次使用springboot?+maven實(shí)現(xiàn),官方demo為springboot+gradle,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07

