java f反射_java反射机制
反射定義
JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
使用反射
1.獲取Class對象
Student類
package com.huchengyue.beans;
public class Student{
private String name;
private int age;
private boolean sex;
public Student(String name, int age, boolean sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public boolean isSex(){
return sex;
}
public void setSex(boolean sex){
this.sex = sex;
}
@Override
public String toString(){
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
main方法
package com.huchengyue;
import com.huchengyue.beans.Student;
public class Fanshe{
public static void main(String[] args){
//第一種方式獲取Class對象
Student stu1 = new Student("sfencs",21,true);//這一new 產生一個Student對象,一個Class對象。
Class stuClass = stu1.getClass();//獲取Class對象
System.out.println(stuClass.getName());
//第二種方式獲取Class對象
Class stuClass2 = Student.class;
System.out.println(stuClass == stuClass2);//判斷第一種方式獲取的Class對象和第二種方式獲取的是否是同一個
//第三種方式獲取Class對象
try {
Class stuClass3 = Class.forName("com.huchengyue.beans.Student");//注意此字符串必須是真實路徑,就是帶包名的類路徑,包名.類名
System.out.println(stuClass3 == stuClass2);//判斷三種方式是否獲取的是同一個Class對象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
2.獲取構造方法并使用
Teacher類
package com.huchengyue.beans;
public class Teacher{
//—————構造方法——————-
//(默認的構造方法)
Teacher(String str){
System.out.println("(默認)的構造方法 s = " + str);
}
//無參構造方法
public Teacher(){
System.out.println("調用了公有、無參構造方法執行了");
}
//有一個參數的構造方法
public Teacher(char name){
System.out.println("姓名:" + name);
}
//有多個參數的構造方法
public Teacher(String name ,int age){
System.out.println("姓名:"+name+"年齡:"+ age);
}
//受保護的構造方法
protected Teacher(boolean n){
System.out.println("受保護的構造方法 n = " + n);
}
//私有構造方法
private Teacher(int age){
System.out.println("私有的構造方法 年齡:"+ age);
}
}
main方法
package com.huchengyue;
import java.lang.reflect.Constructor;
/*
* 通過Class對象可以獲取某個類中的:構造方法、成員變量、成員方法;并訪問成員;
*
* 1.獲取構造方法:
* 1).批量的方法:
* public Constructor[] getConstructors():所有"公有的"構造方法
public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、默認、公有)
* 2).獲取單個的方法,并調用:
* public Constructor getConstructor(Class... parameterTypes):獲取單個的"公有的"構造方法:
* public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"可以是私有的,或受保護、默認、公有;
*
* 調用構造方法:
* Constructor-->newInstance(Object... initargs)
*/
public class Constructors{
public static void main(String[] args) throws Exception{
//1.加載Class對象
Class clazz = Class.forName("com.huchengyue.beans.Teacher");
//2.獲取所有公有構造方法
System.out.println("**********************所有公有構造方法*********************************");
Constructor[] conArray = clazz.getConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("************所有的構造方法(包括:私有、受保護、默認、公有)***************");
conArray = clazz.getDeclaredConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("*****************獲取公有、無參的構造方法*******************************");
Constructor con = clazz.getConstructor(null);
//1>、因為是無參的構造方法所以類型是一個null,不寫也可以:這里需要的是一個參數的類型,切記是類型
//2>、返回的是描述這個無參構造函數的類對象。
System.out.println("con = " + con);
//調用構造方法
Object obj = con.newInstance();
// System.out.println("obj = " + obj);
// Student stu = (Student)obj;
System.out.println("******************獲取私有構造方法,并調用*******************************");
con = clazz.getDeclaredConstructor(char.class);
System.out.println(con);
//調用構造方法
con.setAccessible(true);//暴力訪問(忽略掉訪問修飾符)
obj = con.newInstance('男');
System.out.println(obj);
}
}
3.獲取成員變量并調用
People類
package com.huchengyue.beans;
public class People{
public People(){
}
//**********字段*************//
public String name;
protected int age;
char sex;
private String phoneNum;
@Override
public String toString(){
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", phoneNum='" + phoneNum + '\'' +
'}';
}
}
main方法
package com.huchengyue;
import com.huchengyue.beans.People;
import java.lang.reflect.Field;
/*
* 獲取成員變量并調用:
*
* 1.批量的
* 1).Field[] getFields():獲取所有的"公有字段"
* 2).Field[] getDeclaredFields():獲取所有字段,包括:私有、受保護、默認、公有;
* 2.獲取單個的:
* 1).public Field getField(String fieldName):獲取某個"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):獲取某個字段(可以是私有的)
*
* 設置字段的值:
* Field --> public void set(Object obj,Object value):
* 參數說明:
* 1.obj:要設置的字段所在的對象;
* 2.value:要為字段設置的值;
*
*/
public class Fields{
public static void main(String[] args) throws Exception{
//1.獲取Class對象
Class stuClass = Class.forName("com.huchengyue.beans.People");
//2.獲取字段
System.out.println("************獲取所有公有的字段********************");
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************獲取所有的字段(包括私有、受保護、默認的)********************");
fieldArray = stuClass.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("*************獲取公有字段**并調用***********************************");
Field f = stuClass.getField("name");
System.out.println(f);
//獲取一個對象
Object obj = stuClass.getConstructor().newInstance();//產生Student對象--》Student stu = new Student();
//為字段設置值
f.set(obj, "劉德華");//為Student對象中的name屬性賦值--》stu.name = "劉德華"
//驗證
People peo = (People)obj;
System.out.println("驗證姓名:" + peo.name);
System.out.println("**************獲取私有字段****并調用********************************");
f = stuClass.getDeclaredField("phoneNum");
System.out.println(f);
f.setAccessible(true);//暴力反射,解除私有限定
f.set(obj, "18888889999");
System.out.println("驗證電話:" + peo);
}
}
4,獲取成員方法并調用
student2類
package com.huchengyue.beans;
public class Student2{
public void show1(String s){
System.out.println("調用了:公有的,String參數的show1(): s = " + s);
}
protected void show2(){
System.out.println("調用了:受保護的,無參的show2()");
}
void show3(){
System.out.println("調用了:默認的,無參的show3()");
}
private String show4(int age){
System.out.println("調用了,私有的,并且有返回值的,int參數的show4(): age = " + age);
return "abcd";
}
}
main方法
package com.huchengyue;
import java.lang.reflect.Method;
/*
* 獲取成員方法并調用:
*
* 1.批量的:
* public Method[] getMethods():獲取所有"公有方法";(包含了父類的方法也包含Object類)
* public Method[] getDeclaredMethods():獲取所有的成員方法,包括私有的(不包括繼承的)
* 2.獲取單個的:
* public Method getMethod(String name,Class>... parameterTypes):
* 參數:
* name : 方法名;
* Class ... : 形參的Class類型對象
* public Method getDeclaredMethod(String name,Class>... parameterTypes)
*
* 調用方法:
* Method --> public Object invoke(Object obj,Object... args):
* 參數說明:
* obj : 要調用方法的對象;
* args:調用方式時所傳遞的實參;
):
*/
public class MethodClass{
public static void main(String[] args) throws Exception{
//1.獲取Class對象
Class stuClass = Class.forName("com.huchengyue.beans.Student2");
//2.獲取所有公有方法
System.out.println("***************獲取所有的”公有“方法*******************");
stuClass.getMethods();
Method[] methodArray = stuClass.getMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println("***************獲取所有的方法,包括私有的*******************");
methodArray = stuClass.getDeclaredMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println("***************獲取公有的show1()方法*******************");
Method m = stuClass.getMethod("show1", String.class);
System.out.println(m);
//實例化一個Student對象
Object obj = stuClass.getConstructor().newInstance();
m.invoke(obj, "劉德華");
System.out.println("***************獲取私有的show4()方法******************");
m = stuClass.getDeclaredMethod("show4", int.class);
System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(獲取有反射),一個是實參
System.out.println("返回值:" + result);
}
}
5.通過反射運行配置文件內容
Student3類
package com.huchengyue.beans;
public class Student3{
public void show(){
System.out.println("is show()");
}
}
main方法
package com.huchengyue;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
/*
* 我們利用反射和配置文件,可以使:應用程序更新時,對源碼無需進行任何修改
* 我們只需要將新類發送給客戶端,并修改配置文件即可
*/
public class Demo{
public static void main(String[] args) throws Exception{
//通過反射獲取Class對象
Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"
//2獲取show()方法
Method m = stuClass.getMethod(getValue("methodName"));//show
//3.調用show()方法
m.invoke(stuClass.getConstructor().newInstance());
}
//此方法接收一個key,在配置文件中獲取相應的value
public static String getValue(String key) throws IOException{
Properties pro = new Properties();//獲取配置文件的對象
FileReader in = new FileReader("pro.txt");//獲取輸入流
pro.load(in);//將流加載到配置文件對象中
in.close();
return pro.getProperty(key);//返回根據key獲取的value值
}
}
pro.txt
className = com.huchengyue.Student3
methodName = show
6.通過反射越過泛型檢查
import java.lang.reflect.Method;
import java.util.ArrayList;
/*
* 通過反射越過泛型檢查
*
* 例如:有一個String泛型的集合,怎樣能向這個集合中添加一個Integer類型的值?
*/
public class Demo{
public static void main(String[] args) throws Exception{
ArrayList strList = new ArrayList<>();
strList.add("aaa");
strList.add("bbb");
// strList.add(100);
//獲取ArrayList的Class對象,反向的調用add()方法,添加數據
Class listClass = strList.getClass(); //得到 strList 對象的字節碼 對象
//獲取add()方法
Method m = listClass.getMethod("add", Object.class);
//調用add()方法
m.invoke(strList, 100);
//遍歷集合
for(Object obj : strList){
System.out.println(obj);
}
}
}
?
總結
以上是生活随笔為你收集整理的java f反射_java反射机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java代码解锁华为_如何编写可怕的Ja
- 下一篇: 英国男子官网买iPhone 到手却是高仿