@@ -14,6 +14,7 @@ package scala
14
14
package reflect
15
15
16
16
import java .lang .{ Class => jClass }
17
+ import java .lang .ref .{WeakReference => jWeakReference }
17
18
18
19
import scala .collection .mutable
19
20
import scala .runtime .BoxedUnit
@@ -136,16 +137,19 @@ object ClassTag {
136
137
val Nothing : ClassTag [scala.Nothing ] = Manifest .Nothing
137
138
val Null : ClassTag [scala.Null ] = Manifest .Null
138
139
139
- private [this ] val cache = new ClassValue [ClassTag [_]] {
140
- override def computeValue (runtimeClass : jClass[_]): ClassTag [_] = {
140
+ private val cacheDisabledProp = scala.sys.Prop [String ](" scala.reflect.classtag.cache.disable" )
141
+ private [this ] object cache extends ClassValue [jWeakReference[ClassTag [_]]] {
142
+ override def computeValue (runtimeClass : jClass[_]): jWeakReference[ClassTag [_]] =
143
+ new jWeakReference(computeTag(runtimeClass))
144
+
145
+ def computeTag (runtimeClass : jClass[_]): ClassTag [_] =
141
146
runtimeClass match {
142
147
case x if x.isPrimitive => primitiveClassTag(runtimeClass)
143
148
case ObjectTYPE => ClassTag .Object
144
149
case NothingTYPE => ClassTag .Nothing
145
150
case NullTYPE => ClassTag .Null
146
151
case _ => new GenericClassTag [AnyRef ](runtimeClass)
147
- }
148
- }
152
+ }
149
153
150
154
private def primitiveClassTag [T ](runtimeClass : Class [_]): ClassTag [_] = runtimeClass match {
151
155
case java.lang.Byte .TYPE => ClassTag .Byte
@@ -168,7 +172,19 @@ object ClassTag {
168
172
}
169
173
}
170
174
171
- def apply [T ](runtimeClass1 : jClass[_]): ClassTag [T ] = cache.get(runtimeClass1).asInstanceOf [ClassTag [T ]]
175
+ def apply [T ](runtimeClass1 : jClass[_]): ClassTag [T ] = {
176
+ if (cacheDisabledProp.isSet)
177
+ cache.computeTag(runtimeClass1).asInstanceOf [ClassTag [T ]]
178
+ else {
179
+ val ref = cache.get(runtimeClass1).asInstanceOf [jWeakReference[ClassTag [T ]]]
180
+ var tag = ref.get
181
+ if (tag == null ) {
182
+ cache.remove(runtimeClass1)
183
+ tag = cache.computeTag(runtimeClass1).asInstanceOf [ClassTag [T ]]
184
+ }
185
+ tag
186
+ }
187
+ }
172
188
173
189
def unapply [T ](ctag : ClassTag [T ]): Option [Class [_]] = Some (ctag.runtimeClass)
174
190
}
0 commit comments