2015-09-22 14 views
13

tôi có 2 lớp: FatherChildĐặt giá trị lĩnh vực tư nhân với sự phản ánh

public class Father implements Serializable, JSONInterface { 

    private String a_field; 

    //setter and getter here 

} 

public class Child extends Father { 
    //empty class 
} 

Với phản ánh Tôi muốn thiết a_field trong Child lớp:

Class<?> clazz = Class.forName("Child"); 
Object cc = clazz.newInstance(); 

Field f1 = cc.getClass().getField("a_field"); 
f1.set(cc, "reflecting on life"); 
String str1 = (String) f1.get(cc.getClass()); 
System.out.println("field: " + str1); 

nhưng tôi có một ngoại lệ:

Ngoại lệ trong chuỗi "chính" java.lang.NoSuchFieldException: a_field

Nhưng nếu tôi cố gắng:

Child child = new Child(); 
child.setA_field("123"); 

nó hoạt động.

Sử dụng phương pháp setter Tôi có cùng một vấn đề:

method = cc.getClass().getMethod("setA_field"); 
method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" }); 
+2

Bạn cần phải nhận được lớp cha của lớp đầu tiên, trước khi beeing thể acces lĩnh vực này. [câu hỏi SO khác] (http: // stackoverflow.com/questions/3567372/access-to-private-inherited-fields-qua-reflection-in-java) – SomeJavaGuy

+1

Trường không phải là một phần của lớp con Vì nó là riêng tư, nó thậm chí không hiển thị trong lớp con. setters được công khai và được thừa hưởng, có nghĩa là chúng có thể được gọi là nếu chúng được khai báo trong lớp Child. – f1sh

+0

Thay vì truy xuất trường riêng tư, hãy đặt giá trị của nó bằng cách truy xuất phương thức setter của nó Phương thức –

Trả lời

-4

Theo Javadoc của Class.getField (tôi nhấn mạnh):

Trả về một đối tượng Dòng phản ánh quy định viên công lĩnh vực của lớp hoặc giao diện được đại diện bởi đối tượng Lớp này.

Phương thức này chỉ trả về các trường công khai. Vì a_field là riêng tư, nó sẽ không được tìm thấy.

Dưới đây là một mã làm việc:

public class Main { 

    public static void main(String[] args) throws Exception { 
     Class<?> clazz = Class.forName("Child"); 
     Object cc = clazz.newInstance(); 

     Field f1 = cc.getClass().getField("a_field"); 
     f1.set(cc, "reflecting on life"); 
     String str1 = (String) f1.get(cc); 
     System.out.println("field: " + str1); 
    } 

} 

class Father implements Serializable { 
    public String a_field; 
} 

class Child extends Father { 
//empty class 
} 

Lưu ý rằng tôi cũng thay đổi dòng của bạn String str1 = (String) f1.get(cc.getClass()); để String str1 = (String) f1.get(cc); bởi vì bạn cần phải cung cấp cho các đối tượng của lĩnh vực này, không phải là lớp học.


Nếu bạn muốn giữ trường của mình ở chế độ riêng tư, thì bạn cần truy xuất phương thức getter/setter và gọi các phương thức đó. Mã bạn đã đưa ra không làm việc bởi vì, để có được một phương pháp, bạn cũng cần phải xác định đó là tranh luận, vì vậy

cc.getClass().getMethod("setA_field"); 

phải

cc.getClass().getMethod("setA_field", String.class); 

Dưới đây là một mã làm việc:

public class Main { 

    public static void main(String[] args) throws Exception { 
     Class<?> clazz = Class.forName("Child"); 
     Object cc = clazz.newInstance(); 
     cc.getClass().getMethod("setA_field", String.class).invoke(cc, "aaaaaaaaaaaaaa"); 
     String str1 = (String) cc.getClass().getMethod("getA_field").invoke(cc); 
     System.out.println("field: " + str1); 
    } 

} 

class Father implements Serializable { 

    private String a_field; 

    public String getA_field() { 
     return a_field; 
    } 

    public void setA_field(String a_field) { 
     this.a_field = a_field; 
    } 

} 

class Child extends Father { 
    //empty class 
} 
+0

cảm ơn .. nhưng a_field phải là riêng tư. Alternativelly tôi có thể gọi phương thức setter không? – user1066183

+0

@ user1066183 Tôi đã chỉnh sửa bài đăng của mình. – Tunaki

+0

Cảm ơn, giải pháp của bạn phù hợp với tôi. – user1066183

47

Để truy cập trường riêng tư, bạn cần đặt Field::setAccessible thành true. Bạn có thể kéo trường ra khỏi lớp siêu. Mã này hoạt động:

Class<?> clazz = Child.class; 
Object cc = clazz.newInstance(); 

Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field"); 
f1.setAccessible(true); 
f1.set(cc, "reflecting on life"); 
String str1 = (String) f1.get(cc); 
System.out.println("field: " + str1); 
0

Cái này có thể truy cập vào các lĩnh vực tư nhân cũng không cần phải làm bất cứ điều gì

import org.apache.commons.lang3.reflect.FieldUtils; 
Object value = FieldUtils.readField(entity, fieldName, true); 
Các vấn đề liên quan