From 60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 1 Jul 2010 21:31:21 +0000 Subject: 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. --- src/library/scala/Enumeration.scala | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) (limited to 'src/library') 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 /**

* 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 => "" } + 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) } -- cgit v1.2.3