这不是什么是装箱和拆箱的问题,而是为什么像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)
我的问题,为什么它应该是一个对象,在谈论泛型时,在技术上如此难以包含原始类型?
我有这段代码:
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抱怨这个?
我最近的另一个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) 在运行时,我得到某种类型的盒装实例.如何将其拆箱到基础类型?
Object obj;
String variable = "Some text";
obj = variable // boxing;
// explicit unboxing, because we know the type of variable at compile time.
var x = (String)obj
// Now let's pretend that we don't know the type of underlying object at compile time.
Type desiredType = obj.GetType(); // But we can figure out.
//And now the question.
//How to express something like this:
var y = (desiredType)obj; //Need to get unboxed instance of initial variable here;
Run Code Online (Sandbox Code Playgroud) 为了说明我的问题,请考虑这些简单的例子(C#):
object reference = new StringBuilder();
object box = 42;
object unset = null;
// CASE ONE: bad reference conversions (CIL instrcution 0x74 'castclass')
try
{
string s = (string)reference;
}
catch (InvalidCastException ice)
{
Console.WriteLine(ice.Message); // Unable to cast object of type 'System.Text.StringBuilder' to type 'System.String'.
}
try
{
string s = (string)box;
}
catch (InvalidCastException ice)
{
Console.WriteLine(ice.Message); // Unable to cast object of type 'System.Int32' to type 'System.String'.
}
// CASE TWO: bad unboxing conversions (CIL instrcution …Run Code Online (Sandbox Code Playgroud) Boxing是将值类型转换为托管堆对象的过程,这是隐式的.拆箱是反向过程,编译器需要显式转换.由于拳击存储数据类型,为什么不能拆箱使用它而不是要求显式转换?
class BoxUnBox
{
static void Main()
{
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing - Why is an explicit cast required?
}
}
Run Code Online (Sandbox Code Playgroud) 当方法接受ValueType的out/ref参数时,是否会发生装箱/取消装箱?
我有一个数字应用程序,它使用概率的负对数做了很多工作,其中(因为概率范围从0到1)采用正双精度值或负无穷大值(如果潜在概率为零).
我使用newtype Score如下:
newtype Score = Score Double
deriving (Eq, Ord)
-- ^ A "score" is the negated logarithm of a probability
negLogZero :: Score -- ^ Stands in for - log 0
negLogZero = Score 10e1024
negLogOne :: Score -- ^ - log 1
negLogOne = Score 0.0
unScore :: Score -> Double
unScore (Score x) = x
instance Show Score where
show (Score x) = show x
Run Code Online (Sandbox Code Playgroud)
现在,在Viterbi算法的实现,我已经使用Data.Vector了很多,我确实有一些Data.Vector第Score秒.在尝试进行一些性能调整时,我决定尝试使用Data.Vector.Unboxed.但是,我需要编写一个Unbox …
例如:
int anInt = null;
Run Code Online (Sandbox Code Playgroud)
在编译时失败但是
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("" + getSomeVal());
}
}
public static int getSomeVal() {
return new Random().nextBoolean() ? 1 : null;
}
Run Code Online (Sandbox Code Playgroud)
在运行时(通常)失败.试图返回刚才null也会导致编译错误,所以我假设有多条路径导致编译器推断null可能是自动装箱int?为什么javac能够以相同的错误编译这两种情况?
从JDK 5.0开始,自动装箱/拆箱是在java中引入的,技巧简单而有用,但是当我开始测试包装类和原始类型之间的不同转换时,我真的很困惑自动装箱的概念如何在java中工作,例如:
拳击
int intValue = 0;
Integer intObject = intValue;
byte byteValue = 0;
intObject = byteValue; // ==> Error
Run Code Online (Sandbox Code Playgroud)
尝试不同的情况下(后short,long,float,double),这是由编译器所接受的唯一情况是,当值的上做作运算符右侧的类型是int.当我查看我的源代码时Integer.class发现它只实现了一个带int参数的构造函数.
所以我的结论是自动装箱的概念是基于包装类中实现的构造函数.我想知道这个结论是否属实,还是有自动拳击使用的另一个概念?
拆箱
Integer intObject = new Integer(0);
byte byteValue = intObject; // ==> Error (the same Error with short)
int intValue = intObject;
double doubleValue = intObject;
Run Code Online (Sandbox Code Playgroud)
关于拆箱的结论是包装类给出了对应的类型(Integer==> int)包装的值,然后编译器使用通常的转换基元类型的规则(byte=> short=> int=> long=> float=> double).我想知道这个结论是否属实,还是自动拆箱使用了另一个概念? …