java.io.File field "path" is not declared final
Rémi Forax
forax at univ-mlv.fr
Fri Feb 17 12:00:27 UTC 2012
On 02/17/2012 12:36 PM, Rémi Forax wrote:
> On 02/16/2012 11:37 AM, Alan Bateman wrote:
>> On 15/02/2012 17:34, Rémi Forax wrote:
>>> Reported by a user on the concurrency-interest mailing list,
>>> File field "path" is not declared final but should be.
>> Thanks for forwarding Rémi. I did reply on concurrency-interest but I
>> forgot that my original subscription there was @sun.com.
>>
>> I've created a bug to track this:
>>
>> 7146152: File.path should be final
>>
>> It's something that should have been fixed a long time ago (it's
>> always been non-final). It's just the readObject that requires work,
>> to use unsafe as you suggest.
>>
>> -Alan
>
> Hi Alan, hi all,
> here is a possible fix.
>
> Rémi
>
Better with the attachment inlined :)
Rémi
diff --git a/src/share/classes/java/io/File.java
b/src/share/classes/java/io/File.java
--- a/src/share/classes/java/io/File.java
+++ b/src/share/classes/java/io/File.java
@@ -153,7 +153,7 @@
/**
* The FileSystem object representing the platform's local file
system.
*/
- static private FileSystem fs = FileSystem.getFileSystem();
+ private static final FileSystem fs = FileSystem.getFileSystem();
/**
* This abstract pathname's normalized pathname string. A normalized
@@ -162,13 +162,13 @@
*
* @serial
*/
- private String path;
+ private final String path;
/**
* The length of this abstract pathname's prefix, or zero if it has no
* prefix.
*/
- private transient int prefixLength;
+ private final transient int prefixLength;
/**
* Returns the length of this abstract pathname's prefix.
@@ -2023,10 +2023,28 @@
char sep = s.readChar(); // read the previous separator char
if (sep != separatorChar)
pathField = pathField.replace(sep, separatorChar);
- this.path = fs.normalize(pathField);
- this.prefixLength = fs.prefixLength(this.path);
+ String path = fs.normalize(pathField);
+ UNSAFE.putObject(this, PATH_OFFSET, path);
+ UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET,
fs.prefixLength(path));
}
+ private static final long PATH_OFFSET;
+ private static final long PREFIX_LENGTH_OFFSET;
+ private static final sun.misc.Unsafe UNSAFE;
+ static {
+ try {
+ sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ PATH_OFFSET = unsafe.objectFieldOffset(
+ File.class.getDeclaredField("path"));
+ PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset(
+ File.class.getDeclaredField("prefixLength"));
+ UNSAFE = unsafe;
+ } catch (ReflectiveOperationException e) {
+ throw new Error(e);
+ }
+ }
+
+
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 301077366599181567L;
More information about the core-libs-dev
mailing list