"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Care with type transfer in Java

Care with type transfer in Java

Published on 2024-11-08
Browse:367

Java is a strongly typed language, but it is still possible to transfer values ​​between primitive variables of different types. For example, I can assign the value of an int to a double without any problems, as long as the storage capacity of the type receiving the value can handle it.

See below the size of each primitive type:

Cuidados com transferência de tipos em Java

Transferring value to a type with greater storage capacity has a technical name: "widening conversion". The term in Portuguese is usually translated as "enlargement conversion" or "widening conversion". It refers to the process in which a value from a smaller or more restricted data type is converted to a larger or more comprehensive type without loss of information.

But what if I want to transfer the value to a type with less storage capacity? The Java compiler doesn't like this, but it will allow it if you cast it, as in the example below.

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)

If the size of the value that will go to the new type exceeds the limits of that type, something more dramatic can happen. An int i = 10 fits in a byte variable, as it contains 8 bits in a range from -128 to 127. However, what if I want to put an int i = 128 in a variable of type byte... there will be a loss of information .

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

Autoboxing

In the last post [read it here], I talked a little about the Wrapper classes. As an example, I had written Integer.parse(i) = imagine that i is a type
primitive int.

Currently, using the Wrapper parse method is no longer encouraged as it is deprecated. To transform a primitive into a Wrapper class and, in this way, use built-in methods, it is recommended to do "autoboxing", as in the example:

Character ch = 'a';
Integer i = 10;

Note that this is a more direct approach. You simply assign the value all at once.

To do the opposite and return the data as a primitive type, you can do the "unboxing" using the valueOf:
method

Integer i = 10;
int j = Integer.valueOf(i);

Making the Wrapper of a primitive, as I said in the previous post, has the advantage of allowing you to use the class's methods and making life easier when working with the data.

The wrapper version of a primitive may look a lot like it at first glance, but the JVM does not treat an object and a primitive in the same way, don't forget. Remember that primitives go to the Stack and objects to the Heap [remember here].

In terms of performance, it is clear that retrieving data from a primitive is less costly for the computer, since the value is stored directly, and not by reference. It's much faster to get ready-made data than to keep putting the pieces together in memory.

But there are cases where using a Wrapper will be essential. For example, when you want to work with the ArrayList class. It only accepts objects as parameters, not primitive values.

The flexibility that this transformation from primitive to object and vice versa brings is really cool about the language. But we need to be aware of these pitfalls discussed here and many others.

Just to shock society (lol), I'm going to give an example of a problematic case involving the unexpected behavior of a code when working with overloading (I haven't made a post about overloading yet, but I will. Basically, overloading occurs when a method has different signatures).

This case was mentioned in the book "Effective Java", by Joshua Bloch.

public class SetListTest {
    public static void main(String[] args) {
        Set set = new TreeSet();
        List list = new ArrayList();

        for (int i = -3; i 



In this program, the objective was to add integer values ​​from -3 to 2 [-3, -2, -1, 0, 1, 2] to a set and a list. Then delete the positive values ​​[0, 1 and 2]. But, if you run this code, you will notice that the set and the list did not present the same result. The set returns [-3, -2, -1], as expected. List returns [-2, 0, 2].

This happens because the call to the built-in remove(i) method of the List class treats i as a primitive type int, and nothing else. The method, in turn, removes elements at position i.

The call to the remove(i) method of the Set class calls an overload that receives an Integer object as a parameter, automatically converting i, which was originally an int, to Integer. The behavior of this method, in turn, excludes from the set elements that have a value equal to i (and not an index equal to i) - note that the expected type for both the set and the list was Integer. (Set set / List list). That's why the overloading chosen for the remove method, of the Set class, converted it to Integer.

While the behavior of remove in List is to delete by index, remove in Set is to delete by value. All due to overloading of remove that receives Integer.

Release Statement This article is reproduced at: https://dev.to/anaccortez/cuidados-com-transferencia-de-tipos-em-java-10he?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3