将值类型传递给方法的out参数会导致变量的装箱/取消装箱(从而导致性能下降)吗?编译器可以优化它吗?
int number;
bool result = Int32.TryParse(value, out number);
Run Code Online (Sandbox Code Playgroud) 以下是我对java中重载解析的了解:
编译器尝试从给定的重载方法定义解析方法调用的过程称为重载解析.如果编译器找不到完全匹配,则仅通过使用upcast来查找最接近的匹配(从不进行向下转换).
这是一堂课:
public class MyTest {
public static void main(String[] args) {
MyTest test = new MyTest();
Integer i = 9;
test.TestOverLoad(i);
}
void TestOverLoad(int a){
System.out.println(8);
}
void TestOverLoad(Object a){
System.out.println(10);
}
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,输出为10.
但是,如果我稍微更改类定义并更改第二个重载方法.
public class MyTest {
public static void main(String[] args) {
MyTest test = new MyTest();
Integer i = 9;
test.TestOverLoad(i);
}
void TestOverLoad(int a){
System.out.println(8);
}
void TestOverLoad(String a){
System.out.println(10);
}
}
Run Code Online (Sandbox Code Playgroud)
输出为8.
我在这里很困惑.如果永远不会使用向下转换,那为什么8会被打印出来呢?没有编译器为什么拿起TestOverLoad这需要方法int作为一个垂头丧气从论证Integer到int?
FindBugs给我一个关于以下行的警告,其中invoiceNumber是一个Integer对象:
text.append(String.format("%010d-", (invoiceNumber == null) ? 0 : invoiceNumber));
Run Code Online (Sandbox Code Playgroud)
警告是:"盒装值未装箱,然后立即重新装箱"
现在我觉得我理解(联合国)拳击,但我看不出你怎么会在没有得到警告的情况下做同样的事情?
我发现我可以使用以下代码来消除警告,但这似乎更加冗长:
int invNo = (invoiceNumber == null) ? 0 : invoiceNumber;
text.append(String.format("%010d-", invNo));
Run Code Online (Sandbox Code Playgroud)
有人能告诉我上面做的"正确"方法是什么吗?
顺便说一下,我已经看了相关的问题,我理解他们发生了什么,但这似乎与其中任何一个都不匹配.
以下是有什么区别的:
Integer in = (Integer)y;
和
Integer in = new Integer(y);
我想将int类型转换为Integer类型,反之亦然.这是我的代码:
public class CompareToDemo {
public static void main(String[] args) {
// Integer x=5;
int y=25;
System.out.println(y+" this is int variable");
Integer in = (Integer)y;
//Integer in = new Integer(y);
if(in instanceof Integer){
System.out.println(in +" this is Integer variable");
}
}
}
Run Code Online (Sandbox Code Playgroud) 我在这里想要实现的是盒装基元类型的直接值比较.
((object)12).Equals((object)12); // Type match will result in a value comparison,
((object)12).Equals((object)12d); // but a type mismatch will not. (false)
object.Equals((object)12,(object)12d); // Same here. (false)
Run Code Online (Sandbox Code Playgroud)
我理解'为什么'.我只是没有看到'怎么样'.
这些类型在运行时之前是未知的,它们可以是来自数据源的任何基本类型.这包括字符串,日期时间,bool等等.我已经走下了编写扩展方法的丑陋路线,该方法可以解决两种类型,然后在进行'=='比较之前进行转换:(为了完整性,我包括了每种基本类型,加上我感兴趣的那些)
public static bool ValueEquals(this object thisObj, object compare)
{
if (thisObj is int)
{
int obj = (int)thisObj;
if (compare is int)
return (obj == (int)compare);
if (compare is uint)
return (obj == (uint)compare);
if (compare is decimal)
return (obj == (decimal)compare);
if (compare is float)
return (obj == (float)compare);
<... and so …Run Code Online (Sandbox Code Playgroud) 我知道这是一个非常基本的问题,但我想明确这个概念.我想知道==运算符在原始类型和对象类型的情况下如何工作.例如
Integer a = 1;
int b = 1;
System.out.println(a == b)
Run Code Online (Sandbox Code Playgroud)
如何a与之比较b,而a包含包含值1的对象的引用.有人可以向我清楚它是如何在内部工作的吗?
一位同事检查了这段代码:
Number n = ...;
double nr = n == null ? 0.0 : (double) n;
Run Code Online (Sandbox Code Playgroud)
然后另一位同事抱怨说这没有编译,这就是我所期待的.然而,事实证明我已经从SVN中提取了这些代码并且一切正常.我们都在eclipse中将Java版本设置为1.7,结果证明代码在eclipse 4.4.2(Luna)下编译得很好但在4.2.2下失败了.
我通过替换演员来解决问题n.doubleValue().
现在的实际问题是:为什么这首先被接受了?它当然应该工作的铸造时Double的代替double,但我认为,从直接投Number给double被判无效.那么,这是eclipse 4.2.2中的一个错误,在此期间修复了,或者eclipse 4.4.2是否默默接受不应该编译的代码(恕我直言,这将是一个错误)?
我们现在正在做使用一些迭代等操作x++;,其中x的一个Integer,而不是一个int.
在我们的系统上的一些用户操作中可以重复操作,但没有像数学应用程序那样复杂或太多,每个用户事务最多可达10000次.
这种拆箱和后来的装箱是否会影响我们的性能一些明显的毫秒?
我正在尝试使用Haskell进行数据分析.因为我的数据集相当大(数十万甚至数百万的观测值),所以我最好使用未装箱的数据结构来提高效率,比如Data.Vector.Unboxed.
问题是数据包含一些缺失值.我想避免将它们编码为"99"或类似,因为这只是一个丑陋的黑客和潜在的错误来源.从我的Haskell新手的角度来看,我可以想到以下选项:
Maybe值的盒装矢量.有点像(请纠正错误):data myMaybe a = Nothing | Just {-# UNPACK #-} !anewtype instance Data.Vector.Unboxed.Vector (MyDatum a) = MyDatum (Data.Vector.Unboxed.Vector (Bool,a))Int为Bool),但唯一的答案似乎没有明确解决丢失的问题值/稀疏性(而是关注如何表示整个数组未装箱,而不是作为未装箱矢量的盒装矢量).我试图保持在矢量表示而不是像这样的东西,因为它是稀疏的缺失值,而不是数据.
任何关于这些选项的相对优点/可行性/现成可用性/可能性能的评论,或者确实指向完全不同的替代品,都是受欢迎的!
编辑:
一边琢磨如何最好地映射,即traverse,一个a -> Maybe a-Kleisli在一个未装箱载体,我找了一个现有的实现.显然U.Vector不是Traversable,但它确实提供了一个mapM,Maybe当然工作得很好.
但问题是:Monad真的需要约束吗?好吧,事实证明,甚至盒装向量为Traversable实例作弊:它们实际上只是遍历一个列表,它们从/转换为:
instance Traversable.Traversable Vector where
{-# INLINE traverse #-}
traverse f xs = Data.Vector.fromList Applicative.<$> Traversable.traverse f (toList xs)
Run Code Online (Sandbox Code Playgroud)
mono-traversable 对于未装箱的载体也会做同样的事情 ; 在这里,这似乎更加令人毛骨悚然.
现在,如果vector实际上能够将这些被攻击的遍历融合成更有效的形式,我不会感到惊讶,但仍然 - 似乎存在一个根本问题,阻止我们立即在阵列上实现遍历.这种无能是否存在"深层原因"?
unboxing ×10
java ×6
boxing ×4
c# ×2
haskell ×2
performance ×2
autoboxing ×1
eclipse ×1
equality ×1
findbugs ×1
integer ×1
missing-data ×1
monads ×1
overloading ×1
reflection ×1
value-type ×1