Java Double.valueOf
在我的工作中,所有开发人员都使用构造函数而不是构造函数。在任何情况下。对于整数或短整数,我可以理解为缓存值,但对于Java Double.valueOf,java,jvm,Java,Jvm,在我的工作中,所有开发人员都使用构造函数而不是构造函数。在任何情况下。对于整数或短整数,我可以理解为缓存值,但对于double和float则不能理解 我看起来有双重价值: 所以它只调用Doubles构造函数。 我能理解为什么存在与整数/短字符一致的方法 但对该方法的评论是: 此方法通常应优先于构造函数使用 在我看到每个valueOf()方法上都有相同的注释之后。(整数,短…) 这个评论是假的?还是其他过程的干预 我听说了Java中的内在方法,下一步是在热点代码和 所以在我在源代码中grepDou
double
和float
则不能理解
我看起来有双重价值:
所以它只调用Double
s构造函数。
我能理解为什么存在与整数/短字符一致的方法
但对该方法的评论是:
此方法通常应优先于构造函数使用
在我看到每个valueOf()方法上都有相同的注释之后。(整数,短…)
这个评论是假的?还是其他过程的干预
我听说了Java中的内在方法,下一步是在热点代码和
所以在我在源代码中grepDouble.valueOf
之后,我找到了
和盒子方法代码:
template <typename T>
static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) {
ResourceMark rm(thread);
jclass clazz = env->FindClass(name->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
jmethodID methodID = env->GetStaticMethodID(clazz,
vmSymbols::valueOf_name()->as_C_string(),
sig->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
jobject result = env->CallStaticObjectMethod(clazz, methodID, value);
CHECK_JNI_EXCEPTION_(env, NULL);
return result;
}
模板
静态作业对象框(JavaThread*thread、JNIEnv*env、Symbol*name、Symbol*sig、T值){
资源标记rm(线程);
jclass clazz=env->FindClass(name->as_C_string());
检查异常(env,NULL);
jmethodID=env->GetStaticMethodID(clazz,
vmSymbols::valueOf_name()->作为_C_string(),
sig->as_C_string());
检查异常(env,NULL);
jobject result=env->CallStaticObjectMethod(clazz,methodID,value);
检查异常(env,NULL);
返回结果;
}
这个代码
好的,我还没进阶。在服务器模式下是否真的调用了此方法box()
简历中的3个问题:D
调用此框方法的JVM拦截Double.valueOf()
Double.valueOf
不使用JDK源代码,也不执行新的Double()
Double.valueOf()
上的注释只是一个转储副本/粘贴,Double.valueOf
和new Double
具有相同的效果吗
简而言之:一致性
这是您在编码时应该努力实现的概念,因为它减少了出错的机会,并且使代码更易于阅读
此外,您永远不知道任何时候可能会添加哪些优化,因此请使用valueOf()
方法,除非您需要一个新的Double
值(这是非常罕见的)。仅仅因为它现在不缓存公共值,并不意味着它将来也不会缓存,或者在不同的实现中也不会缓存
这是一个叫做的概念,这也是编码时应该努力实现的
Integer(int)
,Double(Double)
和类似的构造函数都不推荐使用(是的,它们实际上被标记为@deprecated
),因为Java 9是其一部分
事实告诉我们
静态工厂valueOf(double)
通常是更好的选择,因为它可能产生显著更好的空间和时间性能
尽管OpenJDK目前不缓存盒装双精度缓存,但静态工厂方法为将来的优化打开了一条路径。如果决定在JVM或类库中改进Double的自动装箱,那么应用程序将自动从优化中获益,而不需要用户端进行任何更改
另一个原因是,Double.valueOf
确实是HotSpot中的固有方法。JVM将介绍自动装箱方法,并将这些知识用于优化
有两个相关的优化:EliminateAllocations和EliminateAutoBox。尽管它们都是通过逃逸分析提供的,看起来很相似,但它们应用于稍微不同的环境中,因此可能会出现一种优化有效,而另一种优化无效,或者反之亦然
当自动装箱消除成功时,例如,当JIT编译器发现匹配的valueOf
和doubleValue
调用,并且对象没有转义时,优化器将完全消除这两个调用
顺便说一句,提到的代码是无关的。它仅用于内部热点测试目的
该项目目前正在积极开发中,导致对原始包装的全面反思
方法是使用Integer
和double
进行int
和double
的参考投影。作为迁移步骤,Integer
和Double
将成为密封的抽象类,因此无法通过构造函数实例化它们
< P> >,考虑将构造函数作为瓦尔哈拉项目的中间步骤。通过鼓励使用工厂方法,JDK开发人员为他们可以进行的许多优化扫清了道路,包括尽可能地内联Double
实例
从文档中可以看出:“如果不需要新的Double实例,通常应优先使用此方法,而不是构造函数Double(Double),因为此方法可能通过缓存频繁请求的值来产生显著更好的空间和时间性能”-valueOf
允许重用值。是的,还有另一个过程“干预”,即飞锤系统,在该系统中重复使用相同值的对象(不是所有值;通常在字节范围内),而不是构造新对象。如果您想知道为什么valueOf
只是new Double
,这是因为Double#valueOf
有一个通常在运行时使用的。但是,如果禁用了此类优化,则必须有一个默认实现。返回一个新的Double
是默认实现。这是否回答了您的问题?
/* boxing methods: */ \
do_name( valueOf_name, "valueOf") \
do_intrinsic(_Boolean_valueOf, java_lang_Boolean, valueOf_name, Boolean_valueOf_signature, F_S) \
do_name( Boolean_valueOf_signature, "(Z)Ljava/lang/Boolean;") \
do_intrinsic(_Byte_valueOf, java_lang_Byte, valueOf_name, Byte_valueOf_signature, F_S) \
do_name( Byte_valueOf_signature, "(B)Ljava/lang/Byte;") \
do_intrinsic(_Character_valueOf, java_lang_Character, valueOf_name, Character_valueOf_signature, F_S) \
do_name( Character_valueOf_signature, "(C)Ljava/lang/Character;") \
do_intrinsic(_Short_valueOf, java_lang_Short, valueOf_name, Short_valueOf_signature, F_S) \
do_name( Short_valueOf_signature, "(S)Ljava/lang/Short;") \
do_intrinsic(_Integer_valueOf, java_lang_Integer, valueOf_name, Integer_valueOf_signature, F_S) \
do_name( Integer_valueOf_signature, "(I)Ljava/lang/Integer;") \
do_intrinsic(_Long_valueOf, java_lang_Long, valueOf_name, Long_valueOf_signature, F_S) \
do_name( Long_valueOf_signature, "(J)Ljava/lang/Long;") \
do_intrinsic(_Float_valueOf, java_lang_Float, valueOf_name, Float_valueOf_signature, F_S) \
do_name( Float_valueOf_signature, "(F)Ljava/lang/Float;") \
do_intrinsic(_Double_valueOf, java_lang_Double, valueOf_name, Double_valueOf_signature, F_S) \
do_name( Double_valueOf_signature, "(D)Ljava/lang/Double;")
static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) {
return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
}
template <typename T>
static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) {
ResourceMark rm(thread);
jclass clazz = env->FindClass(name->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
jmethodID methodID = env->GetStaticMethodID(clazz,
vmSymbols::valueOf_name()->as_C_string(),
sig->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
jobject result = env->CallStaticObjectMethod(clazz, methodID, value);
CHECK_JNI_EXCEPTION_(env, NULL);
return result;
}