เราสามารถใช้การสะท้อนกลับเพื่อรับสมาชิกแบบคงที่ของคลาสโดยไม่ต้องเรียกใช้เมธอดนั้นบนอินสแตนซ์ของวัตถุได้หรือไม่?

เราสามารถใช้การสะท้อนกลับเพื่อรับสมาชิกแบบคงที่ของคลาสโดยไม่ต้องเรียกใช้เมธอดนั้นบนอินสแตนซ์ของวัตถุได้หรือไม่?

กล่าวอีกนัยหนึ่ง:

 public class MuchoStatic {

    private static staticMember;

    getStaticMember(){

    return this.staticMember;

    }
    } //end class

แล้วมีรหัสเพิ่มเติม:

Method m = null;

try{

  m = MuchoStatic.class.getMethod("getStaticMember",null);

} catch (Exception e) {

}

Object o = null;
try{

 o = m.invoke(MuchoStatic.class,null);

} catch (Exception e) {

}

ฉันได้รับข้อยกเว้นการโต้แย้งที่ผิดกฎหมาย ฉันคิดว่าเป็นเพราะฉันส่งวัตถุ Class ไปยังวิธีการเรียกใช้ ปรากฎว่า Object o ได้รับการติดตั้งจริงแล้ว แต่ข้อยกเว้นยังคงถูกส่งออกไป

เราไม่ควรทำเช่นนี้หรือ?


person Alexander Mills    schedule 26.09.2013    source แหล่งที่มา


คำตอบ (3)


หากเราใช้

setAccessible(true);

กับสนามก็ไม่จำเป็นต้องมีวิธีการในสมการด้วยซ้ำ

Field f = MuchoStatic.class.getField("staticMember");
Object theStatic = f.get(null);

แน่นอนว่า ไม่ ขอแนะนำ... การเข้าไปยุ่งเรื่องส่วนตัวไม่ใช่เรื่องดี อย่าไปยุ่งกับ ความเป็นส่วนตัวของคนอื่น!

ไอเดียนซอ

person ppeterka    schedule 26.09.2013

เราสามารถใช้การสะท้อนกลับเพื่อรับสมาชิกแบบคงที่ของคลาสโดยไม่ต้องเรียกใช้เมธอดนั้นบนอินสแตนซ์ของวัตถุได้หรือไม่?

แน่นอนว่ามันเป็นแบบคงที่

Object o = null;
try {
    Method m = MuchoStatic.class.getMethod("getStaticMember");
    m.setAccessible(true);
    o = m.invoke(null);

} catch (Exception e) {
    // don't ignore the exception as it may be trying to tell you something
    throw new AssertionError(e);
}
person Peter Lawrey    schedule 26.09.2013
comment
ขอบคุณ ฉันลองแล้ว แต่ฉันได้รับ NPE จากภายในวิธีการเรียกใช้ มีวิธีลงสนามโดยตรงโดยไม่ต้องเรียกใช้ getter หรือไม่? - person Alexander Mills; 27.09.2013
comment
@AlexMills ใช่ คุณควรทำให้วิธีการคงที่เนื่องจากไม่จำเป็นต้องมีอินสแตนซ์ - person Peter Lawrey; 27.09.2013

คุณ ไม่จำเป็นต้องมีอินสแตนซ์เพื่อเรียกใช้เมธอดแบบคงที่ และเนื่องจากไม่มีข้อโต้แย้งใดๆ เพียงแค่

o = m.invoke(null);

หากคลาสของคุณไม่ได้อยู่ในแพ็คเกจเดียวกัน คุณจะประสบปัญหา เนื่องจากวิธีการนี้ถูกประกาศเป็นแพ็คเกจส่วนตัว คุณอาจต้องโทร

m.setAccessible(true);

ก่อน invoke()

person Sotirios Delimanolis    schedule 26.09.2013