目錄
一、概念
二、類類
1、類類的獲取方式
1)類名.Class
2)對象.getClass()
3)Class.forName()
三、反射實(shí)例化
1、調(diào)用一個(gè)公有的無參構(gòu)造方法
2、調(diào)用一個(gè)公有的一個(gè)參構(gòu)造方法
3、調(diào)用一個(gè)公有的兩個(gè)參構(gòu)造方法
4、調(diào)用一個(gè)私有的一個(gè)參構(gòu)造方法
四、反射:方法調(diào)用
1、公有無參
2、公有有參
3、私有有參
完整代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-729628.html
五、反射:讀寫屬性
一、概念
J2EE中的反射(Reflection)是指在程序運(yùn)行期間訪問、檢測和修改自身的狀態(tài)或行為。通過反射,可以動(dòng)態(tài)地獲取一個(gè)類的所有成員變量、方法、構(gòu)造函數(shù)等信息,并且可以在運(yùn)行時(shí)調(diào)用這些成員。在J2EE中,反射可以方便地實(shí)現(xiàn)一些框架、ORM工具,以及其他動(dòng)態(tài)性能要求的應(yīng)用程序。
什么是反射?
反射(Reflection)是一種在運(yùn)行時(shí)動(dòng)態(tài)地獲取和操作對象的能力,它允許程序通過對象的類類型來了解對象的成員和方法,并且可以在運(yùn)行時(shí)調(diào)用這些成員和方法。反射可以用于許多目的,例如在運(yùn)行時(shí)動(dòng)態(tài)加載類、實(shí)例化對象、查看和修改對象的屬性和方法、調(diào)用私有方法和構(gòu)造函數(shù),等等。在Java中,反射通過java.lang.reflect包中的類和接口來實(shí)現(xiàn)。反射的優(yōu)點(diǎn)是可以使我們的代碼更加靈活和動(dòng)態(tài),但是反射的開銷比較大,因此在性能要求較高的情況下,應(yīng)該謹(jǐn)慎使用。
總的來說:反射Java語言中的一種機(jī)制,通過這種機(jī)制可以動(dòng)態(tài)的實(shí)例化對象、讀寫屬性、調(diào)用方法
二、類類
在Java反射(reflection)中,Class類被稱為“類類”(class of class),因?yàn)樗砹?span style="color:#ff9900;">JVM中的一個(gè)類。每個(gè)Java類在內(nèi)存中都有一個(gè)對應(yīng)的Class類實(shí)例對象,可以通過Java的反射機(jī)制獲取。通過這個(gè)實(shí)例,我們可以動(dòng)態(tài)地獲取、創(chuàng)建、操作一個(gè)類的各種元數(shù)據(jù)(如屬性、方法、注解等),并可以在程序運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建、修改該類的對象。通過反射,我們可以實(shí)現(xiàn)更加靈活和動(dòng)態(tài)的編程方式,可以在編碼階段不確定訪問的類和方法,直到運(yùn)行時(shí)才確定需要獲取和調(diào)用的類和方法。
1、類類的獲取方式
1. Object類中的getClass()方法:可以獲取一個(gè)對象所屬的類。
2. 類名.class:直接通過類名這種語法形式獲取一個(gè)類的Class實(shí)例對象。
3. Class.forName(String className):通過類的全限定名獲取Class實(shí)例對象,需要處理ClassNotFoundException異常。
這些方式均可以獲得一個(gè)Java類的Class實(shí)例對象,從而可以利用反射機(jī)制獲取該類的一系列信息,如屬性、方法、構(gòu)造方法、注解等。
1)類名.Class
在開始示例的前期準(zhǔn)備工作我們寫一個(gè)類(Class)
package com.tgq.reflect;
/**
* 一個(gè)類
*
* @author tgq
*
*/
public class Student {
private String sid;
private String sname;
public Integer age;
static {
System.out.println("加載進(jìn)jvm中!");
}
public Student() {
super();
System.out.println("調(diào)用無參構(gòu)造方法創(chuàng)建了一個(gè)學(xué)生對象");
}
public Student(String sid) {
super();
this.sid = sid;
System.out.println("調(diào)用帶一個(gè)參數(shù)的構(gòu)造方法創(chuàng)建了一個(gè)學(xué)生對象");
}
public Student(String sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
System.out.println("調(diào)用帶二個(gè)參數(shù)的構(gòu)造方法創(chuàng)建了一個(gè)學(xué)生對象");
}
@SuppressWarnings("unused")
private Student(Integer age) {
System.out.println("調(diào)用Student類私有的構(gòu)造方法創(chuàng)建一個(gè)學(xué)生對象");
this.age = age;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public void hello() {
System.out.println("你好!我是" + this.sname);
}
public void hello(String name) {
System.out.println(name + "你好!我是" + this.sname);
}
@SuppressWarnings("unused")
private Integer add(Integer a, Integer b) {
return new Integer(a.intValue() + b.intValue());
}
}
編寫好一個(gè)類之后我們開始調(diào)用方法進(jìn)行拿去:代碼示例
package com.tgq.reflect;
/**
* 類類的獲取方式: 1、類名.Class 2、對象.getClass(); 3、Class.forName();
*
* @author tgq
*
*/
public class Demo_01 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 1、類名.Class
Class c1 = Student.class;
System.out.println(c1);
}
}
輸出結(jié)果:
2)對象.getClass()
package com.tgq.reflect;
/**
* 類類的獲取方式: 1、類名.Class 2、對象.getClass(); 3、Class.forName();
*
* @author tgq
*
*/
public class Demo_01 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 1、類名.Class
// Class c1 = Student.class;
// System.out.println(c1);
// 2、對象.getClass();
Student student = new Student();
Class c2 = student.getClass();
System.out.println(c2);
}
}
輸出結(jié)果:
3)Class.forName()
package com.tgq.reflect;
/**
* 類類的獲取方式: 1、類名.Class 2、對象.getClass(); 3、Class.forName();
*
* @author tgq
*
*/
public class Demo_01 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 1、類名.Class
// Class c1 = Student.class;
// System.out.println(c1);
// 2、對象.getClass();
// Student student = new Student();
// Class c2 = student.getClass();
// System.out.println(c2);
// 3、Class.forName();
Class c3 = Class.forName("com.tgq.reflect.Student");
System.out.println(c3);
}
}
輸出結(jié)果:
三、反射實(shí)例化
在Java中,可以使用反射來實(shí)例化一個(gè)類。具體實(shí)現(xiàn)可以通過Class類的newInstance()方法或者Constructor類的newInstance()方法來實(shí)現(xiàn)。
三個(gè)常用的方法:getConstructor (),getDeclaredConstructor ()?,newInstance() 。
一切的反射從類類開始
1、調(diào)用一個(gè)公有的無參構(gòu)造方法
public class Demo_02 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 一切反射從類類開始
// 不管是哪一種獲取類類的方法都是可以的
// Class c1 = Class.forName("com.tgq.reflect.Student");
// Student student = new Student();
// Class c1 = student.getClass();
Class c1 = Student.class;
/*
* 1、調(diào)用一個(gè)無參構(gòu)造器反射實(shí)例化: 如果沒有無參構(gòu)造器是會(huì)報(bào)錯(cuò)的
*/
Student stu1 = (Student) c1.newInstance();
System.out.println(stu1);
}
}
輸出結(jié)果:
2、調(diào)用一個(gè)公有的一個(gè)參構(gòu)造方法
public class Demo_02 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 一切反射從類類開始
// 不管是哪一種獲取類類的方法都是可以的
// Class c1 = Class.forName("com.tgq.reflect.Student");
// Student student = new Student();
// Class c1 = student.getClass();
Class c1 = Student.class;
/*
* 1、調(diào)用一個(gè)無參構(gòu)造器反射實(shí)例化: 如果沒有無參構(gòu)造器是會(huì)報(bào)錯(cuò)的
*/
Student stu1 = (Student) c1.newInstance();
System.out.println(stu1);
/*
* 調(diào)用有參構(gòu)造器必須要實(shí)例化構(gòu)造器對象 2、調(diào)用一個(gè)有一個(gè)參數(shù)的構(gòu)造器:getConstructor == 獲取構(gòu)造器對象
*
* parameterTypes:代表了參數(shù)的類別Class
*/
Constructor con1 = c1.getConstructor(String.class);
Student stu2 = (Student) con1.newInstance("s1");
System.out.println(stu2);
}
}
輸出結(jié)果:
3、調(diào)用一個(gè)公有的兩個(gè)參構(gòu)造方法
public class Demo_02 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 一切反射從類類開始
// 不管是哪一種獲取類類的方法都是可以的
// Class c1 = Class.forName("com.tgq.reflect.Student");
// Student student = new Student();
// Class c1 = student.getClass();
Class c1 = Student.class;
/*
* 1、調(diào)用一個(gè)無參構(gòu)造器反射實(shí)例化: 如果沒有無參構(gòu)造器是會(huì)報(bào)錯(cuò)的
*/
Student stu1 = (Student) c1.newInstance();
System.out.println(stu1);
/*
* 調(diào)用有參構(gòu)造器必須要實(shí)例化構(gòu)造器對象 2、調(diào)用一個(gè)有一個(gè)參數(shù)的構(gòu)造器:getConstructor == 獲取構(gòu)造器對象
*
* parameterTypes:代表了參數(shù)的類別Class
*/
Constructor con1 = c1.getConstructor(String.class);
Student stu2 = (Student) con1.newInstance("s1");
System.out.println(stu2);
/*
* 3、調(diào)用兩個(gè)參數(shù)的構(gòu)造器實(shí)例化
*/
Constructor con2 = c1.getConstructor(String.class, String.class);
Student stu3 = (Student) con2.newInstance("s1", "sb");
System.out.println(stu3);
}
}
輸出結(jié)果:
4、調(diào)用一個(gè)私有的一個(gè)參構(gòu)造方法
public class Demo_02 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 一切反射從類類開始
// 不管是哪一種獲取類類的方法都是可以的
// Class c1 = Class.forName("com.tgq.reflect.Student");
// Student student = new Student();
// Class c1 = student.getClass();
Class c1 = Student.class;
/*
* 1、調(diào)用一個(gè)無參構(gòu)造器反射實(shí)例化: 如果沒有無參構(gòu)造器是會(huì)報(bào)錯(cuò)的
*/
Student stu1 = (Student) c1.newInstance();
System.out.println(stu1);
/*
* 調(diào)用有參構(gòu)造器必須要實(shí)例化構(gòu)造器對象 2、調(diào)用一個(gè)有一個(gè)參數(shù)的構(gòu)造器:getConstructor == 獲取構(gòu)造器對象
*
* parameterTypes:代表了參數(shù)的類別Class
*/
Constructor con1 = c1.getConstructor(String.class);
Student stu2 = (Student) con1.newInstance("s1");
System.out.println(stu2);
/*
* 3、調(diào)用兩個(gè)參數(shù)的構(gòu)造器實(shí)例化
*/
Constructor con2 = c1.getConstructor(String.class, String.class);
Student stu3 = (Student) con2.newInstance("s1", "sb");
System.out.println(stu3);
/*
* 4、調(diào)用一個(gè)私有的帶一個(gè)參數(shù)的構(gòu)造器實(shí)例化: getConstructor只能獲取公有的構(gòu)造器對象
*
* getDeclaredConstructor:獲取私有的構(gòu)造器對象
*/
Constructor con3 = c1.getDeclaredConstructor(Integer.class);
// 打開私有的訪問權(quán)限
con3.setAccessible(true);
Student stu4 = (Student) con3.newInstance(1);
System.out.println(stu4);
}
}
輸出結(jié)果:
四、反射:方法調(diào)用
1、公有無參
public class Demo_03 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
// 1、反射調(diào)用 無參方法
Student s = (Student) c.newInstance();
// 反射調(diào)用無參方法,先獲取到方法對象
// name:方法名
// parameterTypes:調(diào)用這個(gè)方法要傳的參數(shù)類型
Method m1 = c.getMethod("hello");
// invoke:方法的返回值
// obj:類示例
// args:參數(shù)值
Object invoke = m1.invoke(s);
System.out.println(invoke);
}
}
輸出結(jié)果:
2、公有有參
public class Demo_03 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
// 1、反射調(diào)用 無參方法
Student s = (Student) c.newInstance();
// 反射調(diào)用無參方法,先獲取到方法對象
// name:方法名
// parameterTypes:調(diào)用這個(gè)方法要傳的參數(shù)類型
Method m1 = c.getMethod("hello");
// invoke:方法的返回值
// obj:類示例
// args:參數(shù)值
Object invoke = m1.invoke(s);
System.out.println(invoke);
// 2、調(diào)用有參方法
Method m2 = c.getMethod("hello", String.class);
Object invoke2 = m2.invoke(s, "asdfghjk");
System.out.println(invoke2);
}
}
輸出結(jié)果:
3、私有有參
public class Demo_03 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
// 1、反射調(diào)用 無參方法
Student s = (Student) c.newInstance();
// 反射調(diào)用無參方法,先獲取到方法對象
// name:方法名
// parameterTypes:調(diào)用這個(gè)方法要傳的參數(shù)類型
Method m1 = c.getMethod("hello");
// invoke:方法的返回值
// obj:類示例
// args:參數(shù)值
Object invoke = m1.invoke(s);
System.out.println(invoke);
// 2、調(diào)用有參方法
Method m2 = c.getMethod("hello", String.class);
Object invoke2 = m2.invoke(s, "asdfghjk");
System.out.println(invoke2);
// 3、調(diào)用有參私有的方法
Method m3 = c.getDeclaredMethod("add", Integer.class, Integer.class);
// 打開私有權(quán)限
m3.setAccessible(true);
Object invoke3 = m3.invoke(s, 1, 2);
System.out.println(invoke3);
}
}
輸出結(jié)果:
完整代碼:
package com.tgq.reflect;
import java.lang.reflect.Method;
/**
* 反射動(dòng)態(tài)方法的調(diào)用
*
* @author tgq
*
*/
public class Demo_03 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
// 1、反射調(diào)用 無參方法
Student s = (Student) c.newInstance();
// 反射調(diào)用無參方法,先獲取到方法對象
// name:方法名
// parameterTypes:調(diào)用這個(gè)方法要傳的參數(shù)類型
Method m1 = c.getMethod("hello");
// invoke:方法的返回值
// obj:類示例
// args:參數(shù)值
Object invoke = m1.invoke(s);
System.out.println(invoke);
// 2、調(diào)用有參方法
Method m2 = c.getMethod("hello", String.class);
Object invoke2 = m2.invoke(s, "asdfghjk");
System.out.println(invoke2);
// 3、調(diào)用有參私有的方法
Method m3 = c.getDeclaredMethod("add", Integer.class, Integer.class);
// 打開私有權(quán)限
m3.setAccessible(true);
Object invoke3 = m3.invoke(s, 1, 2);
System.out.println(invoke3);
}
}
五、反射:讀寫屬性
通過Field類的get()和set()方法來實(shí)現(xiàn)。
拿到我們所有的屬性:
public class Demo_04 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
Student stu = new Student("1", "1A");
// 我們把a(bǔ)ge設(shè)置一個(gè)值
stu.age = 18;
// System.out.println(stu.getSid());
// 獲取對象中全部的屬性
Field[] fields = c.getDeclaredFields();
// 遍歷
for (Field f : fields) {
// 因?yàn)閟id、sname是私有的,所以我們要打開私有權(quán)限
f.setAccessible(true);
// 獲取所有屬性
System.out.println(f.getName() + ":" + f.get(stu));
}
}
}
輸出結(jié)果:
我們進(jìn)行設(shè)置屬性值:
public class Demo_04 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
Student stu = new Student("1", "1A");
// 我們把a(bǔ)ge設(shè)置一個(gè)值
stu.age = 18;
// System.out.println(stu.getSid());
// 拿到屬性
Field snamefield = c.getDeclaredField("sname");
// 打開權(quán)限
snamefield.setAccessible(true);
// 進(jìn)行設(shè)置
snamefield.set(stu, "2B");
// 獲取對象中全部的屬性
Field[] fields = c.getDeclaredFields();
// 遍歷
for (Field f : fields) {
// 因?yàn)閟id、sname是私有的,所以我們要打開私有權(quán)限
f.setAccessible(true);
// 獲取所有屬性
System.out.println(f.getName() + ":" + f.get(stu));
}
}
}
輸出結(jié)果:
文章來源:http://www.zghlxwxcb.cn/news/detail-729628.html
完整代碼:
package com.tgq.reflect;
import java.lang.reflect.Field;
/**
* 反射:讀寫屬性
*
* @author tgq
*
*/
public class Demo_04 {
public static void main(String[] args) throws Exception {
Class c = Student.class;
Student stu = new Student("1", "1A");
// 我們把a(bǔ)ge設(shè)置一個(gè)值
stu.age = 18;
// System.out.println(stu.getSid());
// 拿到屬性
Field snamefield = c.getDeclaredField("sname");
// 打開權(quán)限
snamefield.setAccessible(true);
// 進(jìn)行設(shè)置
snamefield.set(stu, "2B");
// 獲取對象中全部的屬性
Field[] fields = c.getDeclaredFields();
// 遍歷
for (Field f : fields) {
// 因?yàn)閟id、sname是私有的,所以我們要打開私有權(quán)限
f.setAccessible(true);
// 獲取所有屬性
System.out.println(f.getName() + ":" + f.get(stu));
}
}
}
到了這里,關(guān)于Java重點(diǎn):反射機(jī)制的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!