-
Bug
-
Resolution: Won't Fix
-
P3
-
None
-
1.2.0
-
x86
-
windows_nt
Name: rm29839 Date: 05/01/98
import java.lang.reflect.Field;
/**
* This class displays unexpected behavior when trying to change the value of a
* final instance variable through the Reflection API.
*
* This sample was created and compiled using JDK 1.2 Beta 3.
*/
public class BadObject
{
/**
* Main.
*/
public static void main( String args[] )
{
// Create an object:
final BadObject object = new BadObject();
// Grab its string value:
final String string = object.string();
// Print its string value:
System.out.println( string );
}
/**
* Instance variable to hold a string; the important thing to note is that
* it's been declared final.
*/
private final String string = "Initial Value";
/**
* Constructor. It attempts to change the value of the string field using
* the reflection API.
*/
public BadObject()
{
try
{
// Grab a reference to our Class object:
final Class badObjectClass = this.getClass();
// Grab a reference to our string field:
final Field stringField = badObjectClass.getDeclaredField( "string" );
// Key point: Make the string fully accessible to us; i.e., allow us
// to ignore the final keyword attached to the string field;
stringField.setAccessible( true );
// Create a new value to stuff into the field:
final String newValue = "New Value";
// Change the value of the string field:
stringField.set( this, newValue );
}
catch ( final Throwable t )
{
t.printStackTrace();
}
}
/**
* Returns the value in the string field. Note that this method ALWAYS
* returns "Initial Value", rather than the expected "New Value". I assume
* this is due to compiler optimizations which simply look at the final
* keyword attached to the string variable.
*/
public final String string()
{
return this.string;
}
}
(Review ID: 28123)
======================================================================