Java是强类型语言,但仍然可以在不同类型的原始变量之间传输值。例如,我可以将 int 的值分配给 double ,没有任何问题,只要接收该值的类型的存储容量可以处理它。
请参阅下面每种原始类型的大小:
将值转移到具有更大存储容量的类型有一个技术名称:“加宽转换”。该术语在葡萄牙语中通常被翻译为“放大转换”或“加宽转换”。它是指将较小或较受限制的数据类型的值转换为较大或较全面的类型而不丢失信息的过程。
但是如果我想将值转移到存储容量较小的类型怎么办? Java 编译器不喜欢这样,但如果您强制转换它,它会允许这样做,如下例所示。
double decimal = 65.9; int i = (int) decimal; //aqui ele perde a casa decimal e vira 65 char c = (char) i; //aqui ele vira a letra A (que corresponde a 65)
如果传递给新类型的值的大小超出了该类型的限制,则可能会发生更戏剧性的事情。 int i = 10 适合字节变量,因为它包含 -128 到 +127 范围内的 8 位。但是,如果我想将 int i = 128 放入 byte 类型的变量中怎么办...将会丢失信息。
public class Main { public static void main(String[] args) { int i = 128; byte b = (byte) i; System.out.println(b); // o valor de b agora é -128 :S } }
在上一篇文章中[在这里阅读],我谈论了一些关于包装类的内容。作为一个例子,我写了 Integer.parse(i) = 想象 i 是一个类型
原始整数。
目前,不再鼓励使用 Wrapper 解析方法,因为它已被弃用。要将原语转换为包装类并以这种方式使用内置方法,建议进行“自动装箱”,如示例所示:
Character ch = 'a'; Integer i = 10;
请注意,这是一种更直接的方法。只需一次分配所有值即可。
要执行相反的操作并将数据作为原始类型返回,您可以使用 valueOf:
方法进行“拆箱”
Integer i = 10; int j = Integer.valueOf(i);
正如我在上一篇文章中所说,从原语创建包装器的优点是允许您使用类的方法并使处理数据时变得更轻松。
原语的包装版本乍一看可能很像,但是 JVM 不会以相同的方式处理对象和原语,请不要忘记。请记住,基元进入堆栈,对象进入堆[记住这里]。
就性能而言,很明显,从原语检索数据对于计算机来说成本较低,因为值是直接存储的,而不是通过引用存储的。获取现成的数据比将这些数据一直放在内存中要快得多。
但在某些情况下,使用包装器是必不可少的。例如,当您想要使用 ArrayList 类时。它只接受对象作为参数,而不接受原始值。
这种从原始对象到对象的转换所带来的灵活性对于该语言来说真的很酷。但我们需要意识到这里讨论的这些陷阱以及许多其他陷阱。
只是为了震惊社会(笑)我将举一个有问题的案例的例子,涉及重载时代码的意外行为(我还没有发表关于重载的文章,但我会的。基本上,当方法具有不同的签名时就会发生重载)。
Joshua Bloch 所著的《Effective Java》一书中提到了这个案例。
public class SetListTest { public static void main(String[] args) { Set<Integer> set = new TreeSet<>(); List<Integer> list = new ArrayList<>(); for (int i = -3; i < 3; i++) { set.add(i); list.add(i); } for (int i = 0; i < 3; i++) { set.remove(i); list.remove(i); // como corrigir: list.remove((Integer) i); } System.out.println(set + " " + list); }
在此程序中,目标是将 -3 到 2 [-3, -2, -1, 0, 1, 2] 的整数值添加到集合和列表中。然后删除正值[0,1和2]。但是,如果运行此代码,您会注意到集合和列表没有呈现相同的结果。正如预期的那样,该集合返回 [-3, -2, -1]。列表返回 [-2, 0, 2]。
发生这种情况是因为对 List 类的内置 remove(i) 方法的调用将 i 视为基本类型 int,而不是其他类型。该方法依次删除位置 i 处的元素。
调用Set类的remove(i)方法会调用一个重载,该重载接收一个Integer对象作为参数,自动将原本是int的i转换为Integer。反过来,此方法的行为会从集合中排除值等于 i(而不是等于 i 的索引)的元素 - 请注意,集合和列表的预期类型都是 Integer。 (设置设置/列表列表)。这就是为什么为 Set 类中的移除方法选择重载,将其转换为 Integer。
List中的remove行为是按索引删除,而Set中的remove是按值删除。所有这些都是由于接收 Integer 的 remove 超载造成的。
以上是注意 Java 中的类型转换的详细内容。更多信息请关注PHP中文网其他相关文章!