「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Java での型転送に注意する

Java での型転送に注意する

2024 年 11 月 8 日に公開
ブラウズ:511

Java は厳密に型指定された言語ですが、異なる型のプリミティブ変数間で値を転送することは可能です。たとえば、値を受け取る型の記憶容量が処理できる限り、int の値を double に問題なく代入できます。

各プリミティブ タイプのサイズについては以下を参照してください:

Cuidados com transferência de tipos em Java

より大きな記憶容量を持つ型への値の転送には、「拡張変換」という技術名が付いています。この用語はポルトガル語では通常「拡大変換」または「拡大変換」と訳されます。これは、情報を失うことなく、より小さい、またはより制限されたデータ型の値を、より大きい、またはより包括的な型に変換するプロセスを指します。

しかし、ストレージ容量が少ない型に値を転送したい場合はどうすればよいでしょうか? 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 ビットを含むため、byte 変数に収まります。ただし、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
    }
}

オートボクシング

前回の投稿 [ここで読んでください] では、Wrapper クラスについて少しお話しました。例として、Integer.parse(i) = i が型
であると想像してくださいと書きました。 プリミティブ int。

現在、Wrapper parse メソッドは非推奨であるため、使用は推奨されません。プリミティブを Wrapper クラスに変換し、この方法で組み込みメソッドを使用するには、例のように「オートボックス化」を行うことをお勧めします:

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

これはより直接的なアプローチであることに注意してください。一度に値を代入するだけです。

逆を実行してデータをプリミティブ型として返すには、valueOf:
メソッドを使用して「ボックス化解除」を実行できます。

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

前の投稿で述べたように、プリミティブのラッパーを作成すると、クラスのメソッドを使用できるようになり、データの操作が容易になるという利点があります。

プリミティブのラッパー バージョンは一見するとよく似ているように見えますが、JVM はオブジェクトとプリミティブを同じように扱うわけではないことを忘れないでください。プリミティブはスタックに移動し、オブジェクトはヒープに移動することを覚えておいてください [ここを覚えてください]。

パフォーマンスの観点から見ると、値は参照ではなく直接保存されるため、プリミティブからデータを取得する方がコンピューターのコストが低いことは明らかです。断片をメモリ内にまとめ続けるよりも、既成のデータを取得する方がはるかに高速です。

ただし、Wrapper の使用が不可欠な場合もあります。たとえば、ArrayList クラスを操作する場合です。プリミティブ値ではなく、オブジェクトのみをパラメータとして受け入れます。

プリミティブからオブジェクトへ、またはその逆の変換がもたらす柔軟性は、この言語の優れた点です。しかし、ここで説明したこれらの落とし穴や他の多くの落とし穴に注意する必要があります。

社会に衝撃を与えるためだけに (笑)、オーバーロードを扱う際のコードの予期せぬ動作に関連する問題のあるケースの例を示します (オーバーロードについてはまだ投稿していませんが、今後投稿します。)基本的に、オーバーロードはメソッドのシグネチャが異なる場合に発生します)。

この事例は、Joshua Bloch 著「Effective Java」という本で言及されています。

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

        for (int i = -3; i 



このプログラムの目的は、-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 に等しいインデックスではない) 要素がセット要素から除外されます。セットとリストの両方で予期される型は整数であることに注意してください。 (セットセット/リストリスト)。 Set クラスの Remove メソッドに選択されたオーバーロードがそれを Integer.

に変換したのはそのためです。

List の削除の動作はインデックスによって削除されますが、Set の削除は値によって削除されます。すべては、Integer.

を受け取る Remove のオーバーロードが原因です。
リリースステートメント この記事は次の場所に転載されています: https://dev.to/anaccortez/cuidados-com-transferencia-de-tipos-em-java-10he?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3