拳击和拓宽

这两者有什么区别。 我知道Boxing正在将原始值转换为引用。 什么在扩大。 还应该做什么序列第一拳应该做或加宽应该做?

扩展正在用更宽的类型转换另一个变量。
可以使用原始类型或引用类型进行扩展。

例如 :

String – > Object
int – > long

正如JLS所述:

一个拳击转换(§5.1.7) [是]可选地后跟一个加宽的引用转换


资源:

  • JLS – 扩展原始转换
  • JLS – 扩展参考转换
  1. 扩大胜利拳击和var-args
  2. 拳击胜过var-args
  3. 扩展引用变量取决于inheritance(因此,Integer不能扩展为Long。但是,Integer扩展为Number)。
  4. 加宽和拳击是不可能的
  5. 拳击和加宽是可能的
  6. var-args可以与装箱或加宽相结合

扩展是指将byte分配给int 。 即你正在扩大数据类型。

顺序必须boxing然后widening

不能加宽然后框(int不能很长)。

然后你可以加宽框(int可以通过整数成为对象)

注意:突出显示的单词来自Sun认证Java程序员SCJP 6 – Kathy Sierra

  • 加宽节拍拳击例如。 如果两者都可用,则go(int)将调用go(long)而不是go(Integer)
  • 加宽beats var-args例如go(byte,byte)将调用go(int,int)而不是go(byte … x)方法。
  • Boxing beats var-args例如go(byte,byte)将调用go(Byte,Byte)而不是go(byte … x)方法。
  • 扩展取决于inheritance树。 例如。 go(狗)可以打电话去(动物)
  • 原始包装器扩展是不可能的,所以go(Short)不能调用go(Integer),因为它们不在同一个inheritance层次结构中。
  • 你不能加宽然后装箱。 例如。 go(int)不能调用go(Long)因为调用go(Long)编译器需要将int转换为Integer然后将Integer转换为Long,这是不可能的。(上面提到的规则)
  • 您可以装箱然后加宽。 例如。 int可以装箱为Integer,然后加宽到Object

扩展将基元或非基元转换为更宽的类型(即可以容纳更多字节的类型)。

例:

 short -> int String -> Object 

但是, int -> Integer并没有扩大; 这是拳击。 加宽比拳击具有更高的优先级。 拓宽和拳击也不能一起完成,即

 int -> Long // cannot be done - both widening and boxing int -> long // can be done - only widening 

我认为订单非常吸引人。 我做了下面的游乐场,看看每个可能的组合。 这是我的function:

 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..."); } 

规则:

  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... } 

扩展是将数据类型扩展为更广泛的类型。 Boxing是将原始数据类型包装到容器对象中,以便可以在generics中使用,主要是集合。 例如:

 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"); } } 

输出: i am wrapper class Integer (int包装在Integer容器中)

现在让我们取消注释另一个重载方法,看看:

 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"); } } 

输出: I am primitive long

编译器优先级正在扩大自动装箱。

参考