java 拳击和加宽
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3995696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Boxing and Widening
提问by Sumithra
What is the difference between these two. I know Boxing is converting primitive values to reference. What is widening. Also what should be the sequence first boxing should be done or widening should be done?
这两者有什么区别。我知道拳击正在将原始值转换为引用。什么是扩大。另外应该先装箱还是加宽的顺序是什么?
采纳答案by Colin Hebert
Widening is transforming a variable in another with a wider type.
Widening can be done with primitive or reference types.
加宽是将一个变量转换为另一个具有更宽类型的变量。
可以使用原始类型或引用类型进行扩展。
For example :
例如 :
String
-> Object
int
-> long
String
-> Object
int
->long
As the JLS states :
正如 JLS 所说:
a boxing conversion (§5.1.7)[is] optionally followed by a widening reference conversion
装箱转换(第 5.1.7 节)[是] 可选地后跟扩展参考转换
Resources :
资源 :
回答by nisha
- Widening wins over boxing and var-args
- Boxing wins over var-args
- Widening of reference variable depends on inheritance(so, Integer cannot be widened to Long. But, Integer widened to Number).
- Widen and boxing is not possible
- Boxing and widening is possible
- var-args can be combined with either boxing or widening
- 扩大胜过拳击和可变参数
- 拳击战胜了 var-args
- 引用变量的扩展依赖于继承(因此,Integer 不能扩展为 Long。但是,Integer 扩展为 Number)。
- 加宽和拳击是不可能的
- 拳击和加宽是可能的
- var-args 可以与装箱或加宽结合使用
回答by Jigar Joshi
Widening is when assign byte
to int
. i.e. you are widening the data type.
加宽是指分配byte
给int
. 即您正在扩大数据类型。
Sequence must be boxing
then widening
.
顺序必须boxing
然后widening
。
You CANNOTwiden then box (int cannot be Long).
You CANbox then widen (int can become Object via Integer)
你不能加宽然后框(int 不能是 Long)。
您CAN框,然后扩大(INT可以成为通过Integer对象)
Note: Highlighted words are from Sun Certified Java Programmer SCJP 6- Kathy Sierra
注意:突出显示的词来自Sun Certified Java Programmer SCJP 6- Kathy Sierra
回答by Asfanur
- Widening beats boxing eg. go(int) will call go(long) instead of go(Integer) if both are available
- Widening beats var-args eg go(byte,byte) will call go(int,int) instead of go(byte...x) method.
- Boxing beats var-args eg go(byte,byte) will call go(Byte,Byte) instead of go(byte...x) method.
- widening depends on inheritance tree. Eg. go(dog) can call go(Animal)
- primitive wrapper widening is not possible so go(Short) cannot call go(Integer) since they are not in the same inheritance hierarchy .
- You CANNOT widen and then box. Eg. go(int) cannot call go(Long) since to call go(Long) the compiler need to convert int to Integer then Integer to Long which is not possible.(rule mentioned above)
- You can box and then widen. Eg. An int can boxed to Integer and then widen to Object
- 扩大击败拳击例如。如果两者都可用,go(int) 将调用 go(long) 而不是 go(Integer)
- 加宽比 var-args 更好,例如 go(byte,byte) 将调用 go(int,int) 而不是 go(byte...x) 方法。
- 拳击胜过 var-args 例如 go(byte,byte) 将调用 go(Byte,Byte) 而不是 go(byte...x) 方法。
- 扩大取决于继承树。例如。go(dog) 可以调用 go(Animal)
- 原始包装器加宽是不可能的,所以 go(Short) 不能调用 go(Integer) 因为它们不在同一个继承层次结构中。
- 你不能加宽然后装箱。例如。go(int) 不能调用 go(Long),因为要调用 go(Long),编译器需要将 int 转换为 Integer,然后将 Integer 转换为 Long,这是不可能的。(上面提到的规则)
- 你可以装箱然后加宽。例如。一个 int 可以装箱为 Integer 然后加宽为 Object
回答by Sudip Bhandari
Widening is the extension of data type into a wider type. Boxing is when primitive data type is wrapped into a container object so that it can be used in Generics, mainly Collections. Eg:
加宽是将数据类型扩展为更宽的类型。装箱是将原始数据类型包装到容器对象中,以便它可以用于泛型,主要是集合。例如:
public class Widening{
public static void main(String[] args) throws Exception {
int test = 20;
myOverloadedFunction(test);
}
//static void myOverloadedFunction(long parameter) {
//System.out.println("I am primitive long");
//}
static void myOverloadedFunction(Integer parameter) {
System.out.println("i am wrapper class Integer");
}
}
Output:
i am wrapper class Integer
(int is wrapped in Integer container)
输出:
i am wrapper class Integer
(int 被包裹在 Integer 容器中)
Now lets uncomment another overloaded method and see:
现在让我们取消对另一个重载方法的注释,看看:
public class Widening{
public static void main(String[] args) throws Exception {
int test = 20;
myOverloadedFunction(test);
}
static void myOverloadedFunction(long parameter) {
System.out.println("I am primitive long");
}
static void myOverloadedFunction(Integer parameter) {
System.out.println("i am wrapper class Integer");
}
}
Output: I am primitive long
输出: I am primitive long
Compiler precedence is widening over autoboxing.
与自动装箱相比,编译器优先级正在扩大。
回答by Avinash Mishra
Widening is transforming a primitive or non primitive to a wider type (i.e. one that can hold more bytes).
加宽是将原始类型或非原始类型转换为更宽的类型(即可以容纳更多字节的类型)。
Example:
例子:
short -> int
String -> Object
But, int -> Integer
is not widening; it's boxing. Widening has a higher priority than boxing. Also both widening and boxing can't be done together, i.e.
但是,int -> Integer
并没有扩大;这是拳击。加宽比拳击具有更高的优先级。此外,加宽和拳击不能一起完成,即
int -> Long // cannot be done - both widening and boxing
int -> long // can be done - only widening
回答by J. Doe
I think the order is pretty fascinating. I made out the following playground to see every possible combination. This are my functions:
我觉得这个顺序很吸引人。我制作了以下游乐场以查看每种可能的组合。这是我的功能:
static void doSomeThing(short i) {
System.out.println("short");
}
static void doSomeThing(short... i) {
System.out.println("short...");
}
static void doSomeThing(Short i) {
System.out.println("SHORT");
}
static void doSomeThing(Short... i) {
System.out.println("SHORT...");
}
static void doSomeThing(long i) {
System.out.println("long");
}
static void doSomeThing(long... i) {
System.out.println("long...");
}
static void doSomeThing(Long i) {
System.out.println("LONG");
}
static void doSomeThing(Long... i) {
System.out.println("LONG...");
}
static void doSomeThing(int i) {
System.out.println("int");
}
static void doSomeThing(int... i) {
System.out.println("int...");
}
static void doSomeThing(Integer i) {
System.out.println("INTEGER");
}
static void doSomeThing(Integer... i) {
System.out.println("INTEGER...");
}
static void doSomeThing(Object i) {
System.out.println("Object");
}
static void doSomeThing(Object... i) {
System.out.println("Object...");
}
Rules:
规则:
1.Searches for exactly the same type (int -> int)
2.Widening (int -> long)
3.Boxing (int-> Integer, it is NEVER possible to implicit box AND wide (int -> Long NOT possible without cast))
!!Multiple boxing go BEFORE var args!!
int -> Object will be chosen before int -> int...
4.Var args (int -> int...)
5.Widening + var args (int -> long...)
6.Boxing + var args (int -> Integer...)
7.Boxing + widening + var args (int -> Object...)
public class Main{
public static void main(String...args) {
//primitive int
int i = 0;
doSomeThing(i); //int
//commented out doSomeThing(int i){}
doSomeThing(i); //long. It is not possible to narrow, so short, short... Short and Short... will NEVER be called when the input is larger than a short.
//commented out doSomeThing(long i){}
doSomeThing(i); //INTEGER
//commented out doSomething(Integer i){}
doSomeThing(i); //Object. Notice that there can be multiple boxing before moving to var args
//Error occured: compiler if confused: can either execute int..., long..., Object... or Integer...
//Object... and Integer... are commented out, because in the real world int... will be called first
doSomeThing(i); //int...
//commented out int...
doSomeThing(i); //long...
//commented out long... and uncommented Integer...
doSomeThing(i); //Integer...
//commented out Integer... and uncommented Object...
doSomeThing(i); //Object...
//Integer
//Integer
Integer i = new Integer(0);
doSomeThing(i); //INTEGER
//commented out doSomeThing(Integer i)
doSomeThing(i); //Object
//commented out doSomeThing(Object i)
doSomeThing(i); //int
//commented out doSomeThing(int i)
doSomeThing(i); //long so NOT int... it goes widening again
//commented out doSomeThing(long i)
//Error occured: compliler refused: not both have int..., long..., Integer... and Object...
//int... and long... are commented out
doSomeThing(i); //INTEGER...
//commented out doSomeThing(Integer... i)
doSomeThing(i); //Object...
//commented out doSomeThing(Object... i)
//uncommented doSomeThing(int... and long...)
doSomeThing(i); //int...
//uncommented doSomeThing(int... i)
doSomeThing(i); //long...
}