Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>1) <strong><em>How can I access the private methods and the private data members?</em></strong></p> <p>You can do it with a little help of the <code>setAccessible(true)</code> method:</p> <pre><code>class Dummy{ private void foo(){ System.out.println("hello foo()"); } private int i = 10; } class Test{ public static void main(String[] args) throws Exception { Dummy d = new Dummy(); /*--- [INVOKING PRIVATE METHOD] ---*/ Method m = Dummy.class.getDeclaredMethod("foo"); //m.invoke(d); // Exception java.lang.IllegalAccessException m.setAccessible(true);//Abracadabra m.invoke(d); // Now it's OK /*--- [GETING VALUE FROM PRIVATE FIELD] ---*/ Field f = Dummy.class.getDeclaredField("i"); //System.out.println(f.get(d)); // Not accessible now f.setAccessible(true); // Abracadabra System.out.println(f.get(d)); // Now it's OK /*--- [SETTING VALUE OF PRIVATE FIELD] ---*/ Field f2 = Dummy.class.getDeclaredField("i"); //f2.set(d,20); // Not accessible now f2.setAccessible(true); // Abracadabra f2.set(d, 20); // Now it's OK System.out.println(f2.get(d)); } } </code></pre> <p>2) <strong><em>Is it possible to access a local variable via reflection?</em></strong></p> <p>No. Local variables cannot be accessed outside of a block in which they were created (someone could say that you can assign such a variable to a field like <code>field = localVariable;</code> and later access such a field via reflection, but this way we will be accessing the <em>value</em>, not the <em>variable</em>).</p> <p>3) <strong><em>Is there any way to prevent anyone from accessing private constructors, methods, and data members?</em></strong></p> <p>I think for <code>constructors</code> or <code>methods</code> you could use stacktrace to check if it was invoked by <code>Reflection</code>. <br/>For fields I can't find a solution to prevent accessing them via reflection.</p> <h2>[WARNING: This is not approved by anyone. I just wrote it inspired by your question.]</h2> <pre><code>class Dummy { private void safeMethod() { StackTraceElement[] st = new Exception().getStackTrace(); // If a method was invoked by reflection, the stack trace would be similar // to something like this: /* java.lang.Exception at package1.b.Dummy.safeMethod(SomeClass.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) -&gt; at java.lang.reflect.Method.invoke(Method.java:601) at package1.b.Test.main(SomeClass.java:65) */ //5th line marked by "-&gt;" is interesting one so I will try to use that info if (st.length &gt; 5 &amp;&amp; st[4].getClassName().equals("java.lang.reflect.Method")) throw new RuntimeException("safeMethod() is accessible only by Dummy object"); // Now normal code of method System.out.println("code of safe method"); } // I will check if it is possible to normally use that method inside this class public void trySafeMethod(){ safeMethod(); } Dummy() { safeMethod(); } } class Dummy1 extends Dummy {} class Test { public static void main(String[] args) throws Exception { Dummy1 d1 = new Dummy1(); // safeMethod can be invoked inside a superclass constructor d1.trySafeMethod(); // safeMethod can be invoked inside other Dummy class methods System.out.println("-------------------"); // Let's check if it is possible to invoke it via reflection Method m2 = Dummy.class.getDeclaredMethod("safeMethod"); // m.invoke(d);//exception java.lang.IllegalAccessException m2.setAccessible(true); m2.invoke(d1); } } </code></pre> <p><strong>Output from <code>Test</code> main method</strong>:</p> <pre><code>code of safe method code of safe method ------------------- Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at package1.b.Test.main(MyClass2.java:87) Caused by: java.lang.RuntimeException: method safeMethod() is accessible only by Dummy object at package1.b.Dummy.safeMethod(MyClass2.java:54) ... 5 more </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload