这两者有什么区别。我知道拳击正在将原始值转换为参考。什么在扩大。另外应该先做拳击还是扩大应该做的顺序是什么?
7 回答
- 扩大胜过拳击和可变参数
- 拳击战胜 var-args
- 引用变量的扩展取决于继承(因此,Integer 不能扩展为 Long。但是,Integer 扩展为 Number)。
- 扩大和拳击是不可能的
- 装箱和加宽是可能的
- var-args 可以与装箱或加宽结合使用
扩大是用更广泛的类型将一个变量转换为另一个变量。
可以使用原始类型或引用类型进行扩展。
例如 :
String
-> Object
int
->long
正如 JLS 所说:
装箱转换(§5.1.7) [is] 可选地后跟扩大参考转换
资源 :
扩大是分配byte
给int
。即您正在扩大数据类型。
序列必须是boxing
then widening
。
您不能加宽然后框(int 不能是 Long)。
你可以框然后加宽(int可以通过整数变成对象)
注意:突出显示的词来自Sun Certified Java Programmer SCJP 6 - Kathy Sierra
- 扩大击败拳击例如。如果两者都可用, go(int) 将调用 go(long) 而不是 go(Integer)
- 扩大节拍 var-args 例如 go(byte,byte) 将调用 go(int,int) 而不是 go(byte...x) 方法。
- Boxing beat 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
拓宽是将数据类型扩展为更广泛的类型。装箱是将原始数据类型包装到容器对象中,以便可以在泛型(主要是集合)中使用。例如:
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
编译器优先级比自动装箱更广。
加宽是将原始或非原始类型转换为更宽的类型(即可以容纳更多字节的类型)。
例子:
short -> int
String -> Object
但是,int -> Integer
并没有扩大;这是拳击。加宽比拳击具有更高的优先级。也不能同时进行加宽和拳击,即
int -> Long // cannot be done - both widening and boxing
int -> long // can be done - only widening
我觉得这个顺序很吸引人。我制作了以下操场以查看所有可能的组合。这是我的功能:
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...
}