标签: boxing

为什么有些语言需要拳击和拆箱?

这不是什么是装箱和拆箱的问题,而是为什么像Java和C#这样的语言需要呢?

我非常熟悉C++,STL和Boost.

在C++中,我可以很容易地写出这样的东西,

std::vector<double> dummy;
Run Code Online (Sandbox Code Playgroud)

我有一些Java经验,但我真的很惊讶,因为我必须写这样的东西,

ArrayList<Double> dummy = new ArrayList<Double>();
Run Code Online (Sandbox Code Playgroud)

我的问题,为什么它应该是一个对象,在谈论泛型时,在技术上如此难以包含原始类型?

c++ java generics boxing unboxing

30
推荐指数
2
解决办法
8402
查看次数

使用Integer.valueOf(String)查找"使用解析基元进行装箱/取消装箱"的Findbugs

我有这段代码:

public void someMethod(String id) {
   someOtherMethod(Integer.valueOf(id));
}

public void someOtherMethod(int id) {
   // do something with id
}
Run Code Online (Sandbox Code Playgroud)

在第二行,Findbugs抛出了这个异常:

用于解析基元的装箱/拆箱

当我只是调用Integer.valueOf()/我该如何解决这个问题时,为什么Findbugs抱怨这个?

java boxing unboxing findbugs

29
推荐指数
2
解决办法
2万
查看次数

无论类型如何,比较两个整数对象的相等性

我想知道如何比较两个盒装整数(可以是有符号或无符号)以保证相等.

例如,看看这个场景:

// case #1
object int1 = (int)50505;
object int2 = (int)50505;
bool success12 = int1.Equals(int2); // this is true. (pass)

// case #2
int int3 = (int)50505;
ushort int4 = (ushort)50505;
bool success34 = int3.Equals(int4); // this is also true. (pass)

// case #3
object int5 = (int)50505;
object int6 = (ushort)50505;
bool success56 = int5.Equals(int6); // this is false. (fail)
Run Code Online (Sandbox Code Playgroud)

我很难理解如何以这种方式可靠地比较盒装整数类型.直到运行时我才会知道它们是什么,我不能把它们都放到long,因为一个可能是一个ulong.我也不能将它们都转换成两者,ulong因为一个可能是负面的.

我能想到的最好的想法就是试错,直到找到一个普通类型或者可以排除它们不相等,这不是一个理想的解决方案.

.net c# math boxing

29
推荐指数
1
解决办法
6938
查看次数

拳击与拆箱

我最近的另一个C#面试问题是,如果我知道Boxing和Unboxing是什么.我解释了堆上的值类型和Heap上的引用类型.当一个值转换为引用类型时,我们将其称为装箱,反之亦然.

然后他让我计算一下:

int i = 20;
object j = i;
j = 50;
Run Code Online (Sandbox Code Playgroud)

什么是i

我把它搞砸了,然后说了50,它实际上是20.现在我想明白为什么,但是当我玩不同的组合时,我很惊讶地看到这个:

Object a = 1; // Boxing
Object b = a; // referencing the pointer on stack to both objects on heap
a = 2; // Boxing
Run Code Online (Sandbox Code Playgroud)

我期待也能看到b == 2,但事实并非如此,为什么?是因为第二次拳击会破坏并替换a堆上的整个对象吗?

因为如果我这样做,那很好:

public class TT
{
    public int x;
}

TT t = new TT();
t.x = 1;
TT t2 = new TT();
t2.x = 2;
t = t2;
t.x = …
Run Code Online (Sandbox Code Playgroud)

c# boxing unboxing

28
推荐指数
2
解决办法
7174
查看次数

引用值类型的相等性

我做了一些ref关键字测试,有一个认为我无法理解:

static void Test(ref int a, ref int b)
{
    Console.WriteLine(Int32.ReferenceEquals(a,b));
}

static void Main(string[] args)
{
    int a = 4;
    Test(ref a, ref a);
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

为什么显示此代码False?我知道这int是一个值类型,但在这里它应该传递对同一个对象的引用.

c# boxing ref

28
推荐指数
2
解决办法
1542
查看次数

.NET Tuple和Equals性能

这是我直到今天才注意到的事情.显然,当执行基于相等的操作时Tuple<T>,很多使用的元组类(Tuple<T1, T2>等)的.NET实现会导致值类型的装箱惩罚.

以下是该类在框架中的实现方式(来自ILSpy的源代码):

public class Tuple<T1, T2> : IStructuralEquatable 
{
    public T1 Item1 { get; private set; }
    public T2 Item2 { get; private set; }

    public Tuple(T1 item1, T2 item2)
    {
        this.Item1 = item1;
        this.Item2 = item2;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj, EqualityComparer<object>.Default);
    }

    public override int GetHashCode()
    {
        return this.GetHashCode(EqualityComparer<object>.Default);
    }

    public bool Equals(object obj, IEqualityComparer comparer)
    {
        if (obj == null)
        {
            return false;
        }

        var tuple …
Run Code Online (Sandbox Code Playgroud)

.net performance boxing tuples design-decisions

26
推荐指数
1
解决办法
3763
查看次数

将原语与包装器对象进行比较,其中==行为无法解释

我有一段代码需要我理解:

public static void main(String[] args) {
    Character c = new Character('a');
    Character cy = new Character('a');
    char cx = 'a';

    System.out.println(c == cx);
    System.out.println(cx == cy);
    System.out.println(c == cy);
}
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
false
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么只有第三个陈述失败了.

编辑:这个问题.equals==原始与对象比较的vs 问题不同.

java boxing equality equals

26
推荐指数
2
解决办法
3004
查看次数

如何测试值是否在C#/ .NET中装箱?

我正在寻找一种编写代码来测试值是否已装箱的方法.

我的初步调查表明,.NET不顾一切地隐瞒事实,这意味着GetType()IsValueType没有揭示盒装值和未装箱值之间的差异.例如,在下面的LinqPad C#表情,我有信心o1在盒装和i1没有盒装,但是我想一个方法来测试它的代码,或者退而求其次,就无从知道肯定看任何变量时或值,即使它的类型是"动态"或"对象",无论是盒装还是不盒装.

有什么建议?

// boxed? -- no way to tell from these answers!
object o1 = 123;
o1.GetType().Dump("o1.GetType()");
o1.GetType().IsValueType.Dump("o1.GetType().IsValueType");

// not boxed? -- no way to tell from these answers!
int i1 = 123;
i1.GetType().Dump("i1.GetType()");
i1.GetType().IsValueType.Dump("i1.GetType().IsValueType");
Run Code Online (Sandbox Code Playgroud)

.net c# boxing dynamic

25
推荐指数
2
解决办法
4384
查看次数

调用值类型的方法会导致在.NET中装箱吗?

我只是参与Stack Overflow问题.NET中的所有内容都是对象吗?.

并且一张海报(在接受的答案的评论中)似乎认为对值类型执行方法调用导致拳击.他向我指出了Boxing和Unboxing(C#编程指南),它没有明确指出我们描述的用例.

我不是一个信任单一来源的人,所以我只是希望得到关于这个问题的进一步反馈.我的直觉是没有拳击,但我的直觉确实很糟糕.:d

进一步阐述:

我使用的例子是:

int x = 5;
string s = x.ToString(); // Boxing??
Run Code Online (Sandbox Code Playgroud)

如果有问题的结构覆盖从对象继承的方法,则不会发生拳击,如此处所接受的答案所述.

但是,如果结构不覆盖该方法,则在callvirt之前执行"约束" CIL命令.根据文档,OpCodes.Constrained Field,这导致拳击:

如果thisType是一个值类型而thisType没有实现方法,则ptr被解除引用,装箱,并作为'this'指针传递给callvirt方法指令.

.net boxing value-type

24
推荐指数
3
解决办法
2584
查看次数

编译器错误:引用调用模糊

情况1

static void call(Integer i) {
    System.out.println("hi" + i);
}

static void call(int i) {
    System.out.println("hello" + i);
}

public static void main(String... args) {
    call(10);
}
Run Code Online (Sandbox Code Playgroud)

案例1的输出:hello10

案例2

static void call(Integer... i) {
    System.out.println("hi" + i);
}

static void call(int... i) {
    System.out.println("hello" + i);
}

public static void main(String... args) {
    call(10);
}
Run Code Online (Sandbox Code Playgroud)

显示编译错误reference to call ambiguous.但是,我无法理解.为什么?但是,当我评论出任何call()方法时Case 2,它的工作正常.任何人都可以帮助我理解,这里发生了什么?

java methods polymorphism boxing java-7

24
推荐指数
1
解决办法
2万
查看次数