diff options
author | Paul Phillips <paulp@improving.org> | 2010-07-01 21:31:21 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-07-01 21:31:21 +0000 |
commit | 60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be (patch) | |
tree | b7ec7ae608398cd9b58a364c0417c12f4818c435 /src | |
parent | 74eb6b70d58f7f2c3839fb69bc57ffcd00361839 (diff) | |
download | scala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.tar.gz scala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.tar.bz2 scala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.zip |
Took a cue from mharrah that we don't need to b...
Took a cue from mharrah that we don't need to build global static data
to keep track of something when we know where it's kept. Altered the
Enumeration deserialization scheme to use reflection, preserving the
singleton property by delivering the MODULE$ singleton. This solves
the GC issue and lets us drop synchronization to boot. Also added some
graceful failure for malformed Enumerations. All tests look good but a
second opinion is in order: closes #2214, review by phaller.
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/Enumeration.scala | 29 |
1 files changed, 7 insertions, 22 deletions
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 333c6354c0..c7c247fed7 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -6,22 +6,12 @@ ** |/ ** \* */ - - package scala import scala.collection.SetLike import scala.collection.{ mutable, immutable, generic } import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField } - -private object Enumeration { - - /* This map is used to cache enumeration instances for - resolving enumeration _values_ to equal objects (by-reference) - when values are deserialized. */ - private val emap: mutable.Map[Class[_], Enumeration] = new mutable.HashMap - -} +import java.util.NoSuchElementException /** <p> * Defines a finite set of values specific to the enumeration. Typically @@ -69,14 +59,9 @@ abstract class Enumeration(initial: Int, names: String*) { def this() = this(0, null) def this(names: String*) = this(0, names: _*) - /* Populates emap with this instance */ - readResolve() - /* Note that `readResolve` cannot be private, since otherwise the JVM does not invoke it when deserializing subclasses. */ - protected def readResolve(): AnyRef = Enumeration.synchronized { - Enumeration.emap.getOrElseUpdate(getClass, this) - } + protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get() /** The name of this enumeration. */ @@ -246,12 +231,12 @@ abstract class Enumeration(initial: Int, names: String*) { if (nextId > topId) topId = nextId def id = i override def toString() = - if (name == null) thisenum.nameOf(i) - else name + if (name != null) name + else try thisenum.nameOf(i) + catch { case _: NoSuchElementException => "<Invalid enum: no field for #" + i + ">" } + protected def readResolve(): AnyRef = { - val enum = Enumeration.synchronized { - Enumeration.emap.getOrElse(thisenum.getClass, thisenum) - } + val enum = thisenum.readResolve().asInstanceOf[Enumeration] if (enum.vmap == null) this else enum.vmap(i) } |