導航:首頁 > 編程語言 > java反射私有成員

java反射私有成員

發布時間:2023-12-11 04:38:29

1. 既然java反射可以訪問和修改私有成員變數,那封裝成private還有意義么

你沒發現反射訪問是很費力嗎?,private的意義就在於沒想讓人訪問,而JAVA反射的開發在於實現這個功能而已,其實在開發之初也沒想到你用反射只是為了訪問一個私有的變數。

2. java中的反射機制是什麼有什麼作用呢求解,謝謝。

Java反射機制詳解

1. 反射機制是什麼

反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。

2. 反射機制能做什麼

反射機制主要提供了以下功能:

3. 反射機制的相關API

通過一個對象獲得完整的包名和類名

packagenet.xsoftlab.ke;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
TestReflecttestReflect=newTestReflect();
System.out.println(testReflect.getClass().getName());
//結果net.xsoftlab.ke.TestReflect
}
}

實例化Class類對象

packagenet.xsoftlab.ke;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>class1=null;
Class<?>class2=null;
Class<?>class3=null;
//一般採用這種形式
class1=Class.forName("net.xsoftlab.ke.TestReflect");
class2=newTestReflect().getClass();
class3=TestReflect.class;
System.out.println("類名稱"+class1.getName());
System.out.println("類名稱"+class2.getName());
System.out.println("類名稱"+class3.getName());
}
}

獲取一個對象的父類與實現的介面

packagenet.xsoftlab.ke;
importjava.io.Serializable;
{
=-2862585049955236662L;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
//取得父類
Class<?>parentClass=clazz.getSuperclass();
System.out.println("clazz的父類為:"+parentClass.getName());
//clazz的父類為:java.lang.Object
//獲取所有的介面
Class<?>intes[]=clazz.getInterfaces();
System.out.println("clazz實現的介面有:");
for(inti=0;i<intes.length;i++){
System.out.println((i+1)+":"+intes[i].getName());
}
//clazz實現的介面有:
//1:java.io.Serializable
}
}

獲取某個類中的全部構造函數 - 詳見下例

通過反射機制實例化一個類的對象

packagenet.xsoftlab.ke;
importjava.lang.reflect.Constructor;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>class1=null;
class1=Class.forName("net.xsoftlab.ke.User");
//第一種方法,實例化默認構造方法,調用set賦值
Useruser=(User)class1.newInstance();
user.setAge(20);
user.setName("Rollen");
System.out.println(user);
//結果User[age=20,name=Rollen]
//第二種方法取得全部的構造函數使用構造函數賦值
Constructor<?>cons[]=class1.getConstructors();
//查看每個構造方法需要的參數
for(inti=0;i<cons.length;i++){
Class<?>clazzs[]=cons[i].getParameterTypes();
System.out.print("cons["+i+"](");
for(intj=0;j<clazzs.length;j++){
if(j==clazzs.length-1)
System.out.print(clazzs[j].getName());
else
System.out.print(clazzs[j].getName()+",");
}
System.out.println(")");
}
//結果
//cons[0](java.lang.String)
//cons[1](int,java.lang.String)
//cons[2]()
user=(User)cons[0].newInstance("Rollen");
System.out.println(user);
//結果User[age=0,name=Rollen]
user=(User)cons[1].newInstance(20,"Rollen");
System.out.println(user);
//結果User[age=20,name=Rollen]
}
}
classUser{
privateintage;
privateStringname;
publicUser(){
super();
}
publicUser(Stringname){
super();
this.name=name;
}
publicUser(intage,Stringname){
super();
this.age=age;
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
@Override
publicStringtoString(){
return"User[age="+age+",name="+name+"]";
}
}

獲取某個類的全部屬性

packagenet.xsoftlab.ke;
importjava.io.Serializable;
importjava.lang.reflect.Field;
importjava.lang.reflect.Modifier;
{
=-2862585049955236662L;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
System.out.println("===============本類屬性===============");
//取得本類的全部屬性
Field[]field=clazz.getDeclaredFields();
for(inti=0;i<field.length;i++){
//許可權修飾符
intmo=field[i].getModifiers();
Stringpriv=Modifier.toString(mo);
//屬性類型
Class<?>type=field[i].getType();
System.out.println(priv+""+type.getName()+""+field[i].getName()+";");
}

System.out.println("==========實現的介面或者父類的屬性==========");
//取得實現的介面或者父類的屬性
Field[]filed1=clazz.getFields();
for(intj=0;j<filed1.length;j++){
//許可權修飾符
intmo=filed1[j].getModifiers();
Stringpriv=Modifier.toString(mo);
//屬性類型
Class<?>type=filed1[j].getType();
System.out.println(priv+""+type.getName()+""+filed1[j].getName()+";");
}
}
}

通過反射機制調用某個類的方法

packagenet.xsoftlab.ke;
importjava.lang.reflect.Method;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
//調用TestReflect類中的reflect1方法
Methodmethod=clazz.getMethod("reflect1");
method.invoke(clazz.newInstance());
//Java反射機制-調用某個類的方法1.
//調用TestReflect的reflect2方法
method=clazz.getMethod("reflect2",int.class,String.class);
method.invoke(clazz.newInstance(),20,"張三");
//Java反射機制-調用某個類的方法2.
//age->20.name->張三
}
publicvoidreflect1(){
System.out.println("Java反射機制-調用某個類的方法1.");
}
publicvoidreflect2(intage,Stringname){
System.out.println("Java反射機制-調用某個類的方法2.");
System.out.println("age->"+age+".name->"+name);
}
}

通過反射機制操作某個類的屬性

packagenet.xsoftlab.ke;
importjava.lang.reflect.Field;
publicclassTestReflect{
privateStringproprety=null;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
Objectobj=clazz.newInstance();
//可以直接對private的屬性賦值
Fieldfield=clazz.getDeclaredField("proprety");
field.setAccessible(true);
field.set(obj,"Java反射機制");
System.out.println(field.get(obj));
}
}

4. 反射機制的應用實例

在泛型為Integer的ArrayList中存放一個String類型的對象。

packagenet.xsoftlab.ke;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
ArrayList<Integer>list=newArrayList<Integer>();
Methodmethod=list.getClass().getMethod("add",Object.class);
method.invoke(list,"Java反射機制實例。");
System.out.println(list.get(0));
}
}

通過反射取得並修改數組的信息

packagenet.xsoftlab.ke;
importjava.lang.reflect.Array;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
int[]temp={1,2,3,4,5};
Class<?>demo=temp.getClass().getComponentType();
System.out.println("數組類型:"+demo.getName());
System.out.println("數組長度"+Array.getLength(temp));
System.out.println("數組的第一個元素:"+Array.get(temp,0));
Array.set(temp,0,100);
System.out.println("修改之後數組第一個元素為:"+Array.get(temp,0));
}
}

將反射機制應用於工廠模式

packagenet.xsoftlab.ke;
interfacefruit{
publicabstractvoideat();
}
classAppleimplementsfruit{
publicvoideat(){
System.out.println("Apple");
}
}
classOrangeimplementsfruit{
publicvoideat(){
System.out.println("Orange");
}
}
classFactory{
publicstaticfruitgetInstance(StringClassName){
fruitf=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch(Exceptione){
e.printStackTrace();
}
returnf;
}
}
/**
*對於普通的工廠模式當我們在添加一個子類的時候,就需要對應的修改工廠類。當我們添加很多的子類的時候,會很麻煩。
*Java工廠模式可以參考
*http://ke.xsoftlab.net/view/java-factory-pattern
*
*現在我們利用反射機制實現工廠模式,可以在不修改工廠類的情況下添加任意多個子類。
*
*但是有一點仍然很麻煩,就是需要知道完整的包名和類名,這里可以使用properties配置文件來完成。
*
*java讀取properties配置文件的方法可以參考
*http://ke.xsoftlab.net/view/java-read-the-properties-configuration-file
*
*@authorxsoftlab.net
*/
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
fruitf=Factory.getInstance("net.xsoftlab.ke.Apple");
if(f!=null){
f.eat();
}
}
}
我有一個微信公眾號,經常會分享一些Java技術相關的干貨,還有一些學習資源。
如果你喜歡我的分享,可以用微信搜索「Java團長」或者「javatuanzhang」關注。

3. java 怎麼用反射訪問私有變數

field2.setAccessible(true);
訪問之前對訪問的屬性加上上面這句話才行。

4. Java反射 在只知道類名的情況下,怎樣給其中的私有屬性賦值

利用反射能

//假設類名為A
//實例化類
Ap=newA();
//獲取class
Classc=p.getClass();
//獲取該類所有的欄位
Field[]fields=c.getDeclaredFields();
//遍歷賦值
for(inti=0;i<fields.length;i++){
StringfiledName=fields[i].getName();
//AccessibleTest類中的成員變數為private,故必須進行此操作
fields[i].setAccessible(true);
//判斷類型
Class<?>type=fields[i].getType();
//獲取欄位類型
StringtypeName=type.getName();
System.out.println(type.getName());

//對欄位進行賦值第一個參數為對象引用第二個參數為要附的值

//如果為字元串類型
if("java.lang.String".equals(typeName)){
fields[i].set(p,"1");
}
//如果為日期類型
elseif("java.util.Date".equals(typeName)){
fields[i].set(p,newDate());
}
else{
fields[i].set(p,1);
}

}

//樓主我只是簡單的寫了下。可能還需要判斷欄位名稱以及其他類型什麼的。



最後希望樓主多看看java 文檔。

5. java 反射 訪問父類私有成員

可以看看這個 但是跟反射沒什麼關系。
利用多態,子類雖然訪問不了父類的私有變數,但是可以通過方法訪問,see

class a{
private int i = 11;
public void show(){
System.out.println(i);
}
}

class b extends a{
private int j= 12;
public static void main(String[] args){
a aa = new b();
aa.show();
}
}

6. java反射訪問私有方法的的問題

java的反射可以繞過訪問許可權,訪問到類的私有方法和成員。可能這點會引起安全性的討論。反射的使用幫助解決很多復雜的問題,其運行時的類型檢查,動態調用,代理的實現等,反射為我們寫程序帶來了很大的靈活性,很多功能都是基於反射。
利用反射還可以訪問內部類、匿名內部類的私有屬性。
用java自帶的java -private 類名 反編譯命令可以查看類的完整定義。(參考think in java)
下面舉例子說明。首先定義一個介面
Java代碼
public interface Ref {
public void f();
}
public interface Ref {
public void f();
}
介面的實現類
Java代碼
public class RefImpl implements Ref {
//實現介面方法
public void f() {
System.out.println("public method f()");
}

void g(String args){
System.out.println("package method g():" + args);
}

private void w(){
System.out.println("private method w()");
}
}
public class RefImpl implements Ref {
//實現介面方法
public void f() {
System.out.println("public method f()");
}

void g(String args){
System.out.println("package method g():" + args);
}

private void w(){
System.out.println("private method w()");
}
}
測試類
Java代碼
public class TestRef {

public static void main(String[] args) {
Ref ref = new RefImpl();
System.out.println(ref.getClass().getSimpleName()); //RefImpl類型
ref.f(); //調用介面方法
// ref.g(); //向上轉型後實現類添加的方法不能調用
if(ref instanceof RefImpl){
RefImpl ref1 = (RefImpl)ref; //類型識別後轉型
ref1.g("zhouyang");
// ref1.w(); //私有方法不能訪問
}

//通過反射調用方法
try {
Ref ref2 = new RefImpl();
Method m = ref2.getClass().getDeclaredMethod("f");
Method m1 = ref2.getClass().getDeclaredMethod("g", String.class);//有參的方法
Method m2 = ref2.getClass().getDeclaredMethod("w");
System.out.println("==============");
m.invoke(ref); //調用方法f()
m1.invoke(ref, "yangzhou");

m2.setAccessible(true);///調用private方法的關鍵一句話
m2.invoke(ref);
} catch (Exception e) {
e.printStackTrace();
}

//java的javap反編譯能夠查看類的信息,-private 開關能夠打開所有信息
//javap -private 類名 類必須是編譯成.calss 文件

//利用反射訪問私有成員,改變私有成員值,但是final域可以訪問不可改變
PrivateField pf = new PrivateField();
// ps.ss; //私有成員不能訪問
//列印原來的成員值
pf.print();
try {
//反射訪問和改變原來值
Field[] f = pf.getClass().getDeclaredFields();
for(int i=0;i<f.length;i++){
f[i].setAccessible(true);
System.out.println(f[i].getType());//列印欄位類型
System.out.println(f[i].get(pf)); //列印值
if("ss".equals(f[i].getName())){
f[i].set(pf, "hehe"); //修改成員值
}else{
f[i].setInt(pf, 55);
}

}
//重新列印修改後的成員值,final域值不變
pf.print();
} catch (Exception e) {
e.printStackTrace();
}
/*列印輸出的結果
* RefImpl
public method f()
&nb

7. 一個java對象的屬性是私有的,而且沒有提供public的get和set方法,可以用反射的方式將其轉成json嗎

如果提供了get和set方法是可以實現的,因為變數是私有的,只能通過外部公用方法去訪問這些變數,如果沒有這些方法就只能通過本類訪問,其他類沒有辦法訪問

閱讀全文

與java反射私有成員相關的資料

熱點內容
如何加密qq空間日誌 瀏覽:432
環衛車壓縮箱有多重 瀏覽:746
換手率app怎麼沒有自媒體了 瀏覽:407
安卓如何區分展示機和正品機 瀏覽:371
java運行和編譯命令 瀏覽:543
手機解壓30g文件要多久 瀏覽:708
php讀取文件格式 瀏覽:612
開發程序員的電影 瀏覽:743
pc端解壓文件下載 瀏覽:708
單片機C語言讀寄存器 瀏覽:164
linux火車源碼 瀏覽:793
小米手機應用加密怎樣解除 瀏覽:523
幫孩子解壓的句子 瀏覽:140
木匠編程 瀏覽:832
笑話pdf 瀏覽:441
pdf變形 瀏覽:852
微信app最下面的菜單欄叫什麼 瀏覽:249
我的世界晚上七點有什麼伺服器 瀏覽:176
雲伺服器不見了怎麼辦 瀏覽:967
怎麼看電腦ntp伺服器地址 瀏覽:579