Java:为什么有人要加宽和缩短变量?

Java:为什么有人要加宽和缩短变量?,java,type-conversion,Java,Type Conversion,我正在lynda.com上学习一门java课程,这门课程解释了如果想要缩短变量,如何“强制转换”变量 加宽:加宽变量使其变大(例如int int1=4030;long long1=int1;) 缩短:缩短变量会使其变小,并且需要特殊的语法。(例如int int2=5024;short int3=(short)int2;) 所以,我的问题是,为什么会有人想这样做?有什么好处?如果你知道在某个时刻你需要加宽一个变量,为什么不把它作为那个变量开始呢?如果要缩短,为什么要使数据类型更小?如果您认为它可以

我正在lynda.com上学习一门java课程,这门课程解释了如果想要缩短变量,如何“强制转换”变量

加宽:加宽变量使其变大(例如int int1=4030;long long1=int1;)

缩短:缩短变量会使其变小,并且需要特殊的语法。(例如int int2=5024;short int3=(short)int2;)

所以,我的问题是,为什么会有人想这样做?有什么好处?如果你知道在某个时刻你需要加宽一个变量,为什么不把它作为那个变量开始呢?如果要缩短,为什么要使数据类型更小?如果您认为它可以这样使用:

byte byte1 = 127;

byte1++;

if (byte1 > 127) {
     short short1 = byte1;
}
(我知道这会给出一条错误消息,但您可以大致了解。)


你可以这么做,但为什么?它不会保存数据,因为它只会添加更多的代码行来占用数据。

您可能需要“缩短”变量有几个原因

一个是您正在使用的API或库要求传递的数据类型比您在代码中使用的类型“短”

另一个是节省空间。例如,如果我只需要存储一个两位数的数字,那么使用
long
将是过分的,因为它将使用比所需多得多的系统内存。这通常不需要太担心,但对于某些系统或非常大的项目,这可能是一个问题


原因可能更多,;这些只是几个例子。

假设您想要实现一个
min(…)
方法来计算两个数字中的最小值。你可以简单地写:

public static double min(double lhs, double rhs) {
    if (lhs >= rhs) {
        return (lhs);
    }
    // else if (rhs > lhs) {
    return (rhs);
    // }
通过自动转换(或者您称之为“加宽”),您可以使用Java中的所有原语调用此方法。但是,缺点是结果总是
double
,如果要将其保存为
int
,则必须向下转换结果:

int i1 = 0;
int i2 = 100;
int max = (int) max(i1, i2);
如果该方法返回一个
int
iff就好了。这两个参数都是
int
,一个
long
iff。一个参数是
long
,另一个参数是
long
int
,依此类推。这将导致以下代码1:

然后你可以写:

int i = 0;
long g = 1L;
float f = 2f;
double d = 3.0;

int intMax = max(i, i);
long longMax = max(i, g);
float floatMax = max(i, f);
double doubleMax = max(l, d);
通过自动广播和,最具体的方法将被称为2,3


1您可以为
byte
short
char
编写这些方法。我不建议这样做,因为Java中的所有算术运算都至少返回
int
类型的内容(例如
byte+byte
将返回
int
)。这是因为JVM不知道原语
boolean
char
byte
short
,它们表示为
int
(请参阅)

2中规定了确切的行为


3这实际上是用于实现
min(…)
的相同机制,其实现略有不同。

如果必须将从一个不受您控制的函数接收的值传递到另一个也不受您控制的函数,则绝对无法避免此问题:

包abc.def:

public class Foo {
    public static long foo() { ... }
}
public class Bar {
    public static void bar(int n) { ... }
}
import xyz.qwerty.Bar;
import abc.def.Foo;

...

     Bar.bar((int)Foo.foo());
程序包xyz.qwerty:

public class Foo {
    public static long foo() { ... }
}
public class Bar {
    public static void bar(int n) { ... }
}
import xyz.qwerty.Bar;
import abc.def.Foo;

...

     Bar.bar((int)Foo.foo());
您的代码:

public class Foo {
    public static long foo() { ... }
}
public class Bar {
    public static void bar(int n) { ... }
}
import xyz.qwerty.Bar;
import abc.def.Foo;

...

     Bar.bar((int)Foo.foo());

在到达
Bar.Bar()
之前,可能会有中间变量暂时保存从
Foo.Foo()
接收到的值,但这并不能消除从一种类型转换为另一种类型的必然需要,这必须发生在两者之间。

如果您使用的接口要求的类型与代码的类型不同,则可能需要加宽或缩短变量。另外,作为旁注:您真的不需要考虑通过编写更少的代码行可以节省多少内存,这几乎不会有任何意义(除非你是为一个严格限制的系统写的)。您应该关注如何以及使用哪些数据结构来解决哪些问题,以便在处理大量数据时获得最佳(/非常好)性能。需要缩短时间的一个示例是,您希望将
双精度
四舍五入为
整数。
int
是四个字节,而
double
是八个字节。因此,您必须显式地强制转换为
int
@TimBiegeleisen如果您知道您使用的API只适用于
byte
s,为什么要声明
int
变量和“shorten”它?@Sweeper我想的更多的是,你继承了一些使用
int
的代码,但是后来又有了一个新的需求,需要与
byte
接口。