まず、基本的な
1.1正しい使用は、equalsメソッドを
容易ポインタ例外を短絡オブジェクトのメソッドに等しく、定数または決定オブジェクトがコールに等しい値と一緒に使用されるべきです。次のコード
// そうでない場合は例外がスローされ、参照型変数非静的メソッド呼び出しにNULL値を使用することができない 文字列STR = NULL ; IF(str.equals(「SnailClimb」)){ ... } 他{ .. } / / ヌルポインタ例外がスローされますが、我々はこのような場合、次の文を2行目の条件を決定し、それがnullポインタ例外をスローしません上記の手順を実行して、文のelseブロックが実行されます。 "SnailClimb" .equals(STR); // falseを // しかし、もっと推奨されjava.util.Objects#イコール(JDK7は、ツールを導入しました)。 Objects.equals(ヌル、 "SnailClimb"); // falseに 出所: パブリック 静的 ブールのequals(オブジェクトA、オブジェクトB){ // 回避のヌルポインタ例外。この時点であれば、==ヌルa.equals(b)は、ヌル・ポインター例外を避けるために実装されることはありません。 リターン(== b)の|| (!= nullの && a.equals(b)参照)。 }
.equals(前)を呼び出すときequalsメソッドを後に入力、「定数」.equals(変数)に従うか、してください。これは通常、習慣を養うためにもっと注意を払う未来が隠されて横たわってい防ぐ、NULLポインタエラーを回避します。
知識サプリメント
ヌルについて、あなたはいくつかのことを知っている必要があります:
1、ヌルは、最終的に公共の、静的な、などのJavaキーワードです。それはあなたではなく、書き込みヌルヌルまたはNULL、コンパイラがそれらを認識し、エラーはありませんすることができ、大文字と小文字が区別されます。
図2に示すように、各プリミティブ型は、デフォルト値は0であるようintとしてデフォルト値を有しているだけのように、ブールデフォルト値は偽であり、ヌルは、任意の参照型のデフォルト値であり、厳密に言えば、すべてのオブジェクトタイプのデフォルトはありません。あなたはブール変数を作成すると、それは彼らのデフォルト値としてfalseになり、Javaの任意の参照変数は、デフォルトではnullです。これは、メンバ変数、ローカル変数、インスタンス変数、静的変数としてすべての変数、に適用されます(ただし、初期化されていないローカル変数を使用し、コンパイラは警告を表示します)。この事実を証明するために、あなたは、参照変数を観察するために、変数を作成することによって、その値を印刷することができます。
。3、ヌルやオブジェクトの種類も、それはあなたが任意の参照型を付与することができる唯一の特別な値であり、また、任意のタイプのヌルに変換することができます。
4、nullが参照変数に割り当てることができ、あなたは、int型、ダブル、フロート、ブールなどの変数の代入ヌル基本タイプを、することはできません。あなたがそれを行う場合、コンパイラはエラーを報告します。
図5は、基本データ型のJava開梱時間を生成するヌル値を含む任意のパッケージングは、ヌル・ポインタ例外をスローします。(例えば、整数intとしてアンパック)
図6は、NULL値を持つ参照型の変数場合、instanceofの操作は偽を返します。(INSTANCEOFは:整数NUM = NULL整数のinstanceof NUMを呼び出すときにfalseを返す、:オブジェクトのような、特定のクラスのインスタンスである場合、実行時に指摘して)
7は、参照型の変数のNULL値を使用する非静的メソッドを呼び出すことはできません、それはヌルポインタ例外がスローされます。あなたは、静的メソッドは静的バインディングを使用しているため、参照型変数のNULL値を使用するように静的メソッドを使用することができ、ヌルポインタ例外をスローしません。
8、あなたが使用することができますか==!= NULL値の比較演算が、そのようなより少ない以上のように、アルゴリズムまたは他の論理演算を使用することはできません。SQLと同じではありませんが、Javaのnull == nullをtrueを返します。
1.2比較包装整数値
すべての包装整数比較対象値は、メソッドを使用する必要があります等しいです。
1整数X = 3 。 2整数Y = 3 。 3のSystem.out.println(x == y)は、// 真 4整数= 新しい整数(3 )。 5整数B = 新しい整数(3 )。 6のSystem.out.println(== B)。// 偽 7のSystem.out.println(a.equals(b)参照)。// 真
再び値次回は、キャッシュから直接取得Integerオブジェクトに対応する場合、作成される-128〜127の値は、整数オブジェクトをキャッシュされた自動包装モードを使用して、Integerオブジェクトを作成する場合。したがって、上記のコードは、X及びYは同じIntegerオブジェクトを参照します。
注:アリババはP3CプラグインあなたのIDE(IDEA /エクリプス)にインストールした場合、あなたは==使用する場合は、このプラグインが検出され、その後、エラーが要求されます、それは、プラグイン、非常に良いをインストールすることをお勧めします。
1.3BigDecimal
1.3.1。BigDecimalの有用性
「マニュアルアリババJavaの開発」を参照:フロート間の等価性を決定し、基本データ型は等号によって判断することができないデータ型をパッケージ化、比較するために==を使用することはできません。具体的な原則と、ここについてのフロートをコーディングすることはもちろんのことで、私たちは、次の例を指示します:
1台の フロート A = 1.0F - 0.9f 。 2 フロート B = 0.9f - 0.8f 。 3のSystem.out.println(); // 0.100000024 4のSystem.out.println(B)。// 0.099999964 5のSystem.out.println(== B)。// 偽
私たちは、数学の基本的な知識を持って明確にどのように我々はこの問題を解決するか、出力は、我々は(精度の損失)望むものではないことを知っていますか?非常に一般的な方法は、次のとおりのBigDecimalその使用浮動小数点数は、浮動小数点演算を定義します。
BigDecimalのA = 新しい BigDecimalを( "1.0" ); BのBigDecimal = 新しい BigDecimalを( "0.9" ); BigDecimalのC = 新しい BigDecimalを( "0.8" ); BigDecimalをX = a.subtract(B)。// 0.1 のBigDecimal Y = b.subtract(C); // 0.1 するSystem.out.println(x.equals(Y))。// 真
1.3.2。BigDecimalの大きさを比較
a.compareTo(b)
:-1 0に等しい、未満示すために1よりも大きいこと、を示しています。
BigDecimalのA = 新しい BigDecimalを( "1.0" ); BのBigDecimal = 新しい BigDecimalを( "0.9" ); System.out.println(a.compareTo(b)参照)。// 1
1.3.3。BigDecimalのには、いくつかの小数点以下の桁数を予約しました
setScale
セット保持ルールにいくつかの小数点以下の桁数や方法を保持します。非常に多様であり、何の記録保持ルールは、IDEAは、プロンプトが表示されません。
BigDecimalをM = 新規のBigDecimal( "1.255433" )。 BigDecimalのN = m.setScale(3 、BigDecimal.ROUND_HALF_DOWN)。 System.out.println(N)// 1.255
使用するために1.3.4。BigDecimalの注意事項
注:私たちはBigDecimalのを使用し、精度の低下を防止するためには、オブジェクトを作成するのBigDecimal(String)コンストラクタを使用することをお勧めします。「マニュアルアリババのJava Development、」以下に示すように、コンテンツのこの部分にも言及されています。
1.3.5まとめ
BigDecimalのは、主に(大)フロートを動作させるために使用され、BigIntegerのは、主に(長い上型)大きな整数を操作するために使用されます。
BigDecimalのはBigIntegerのを使用して達成するために、差がコンセプトのBigDecimal小数点以下の桁数に加算されます
1.4。基本データ型と標準を使用してパッケージのデータ型
参考:「アリ・ババのJava開発マニュアル」
- [必須]すべてのPOJOクラスのプロパティは、データタイプをパッケージに使用しなければなりません。
- [フォース] RPCパラメータと戻り値のデータ型のパッケージを使用する必要があります。
- 基本データ型を使用して、すべてのローカル変数を[推奨]。
たとえば、私たちは生徒の成績スコアは、整数ではなくint型の定義で、受験、学生が値をテストしていない可能性がある場合はnullである、それはテストすることがプロパティを持つクラス、が、試験0をカスタマイズした場合、値0で、この2つの状態の表現は明らかに同じではありません。
说明 :POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何 NPE 问题,或者入库检查,都由使用者来保证。
正例 : 数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险。
反例 : 比如显示成交总额涨跌情况,即正负 x%,x 为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示为 0%,这是不合理的,应该显示成中划线。所以包装数据类型的 null 值,能够表示额外的信息,如:远程调用失败,异常退出。
2. 集合
2.1. Arrays.asList()使用指南
Arrays.asList()在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。
String[] myArray = { "Apple", "Banana", "Orange" }; List<String> myList = Arrays.asList(myArray); //上面两个语句等价于下面一条语句 List<String> myList = Arrays.asList("Apple","Banana", "Orange");
JDK 源码对于这个方法的说明:
/** *返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。 */ public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
2.1.2. 《阿里巴巴Java 开发手册》对其的描述
Arrays.asList()
将数组转换为集合后,底层其实还是数组,《阿里巴巴Java 开发手册》对于这个方法有如下描述、
2.1.3. 使用时的注意事项总结
传递的数组必须是对象数组,而不是基本类型。
Arrays.asList()是泛型方法,传入的对象必须是对象数组。
1 int[] myArray = { 1, 2, 3 }; 2 List myList = Arrays.asList(myArray); 3 System.out.println(myList.size());//1 4 System.out.println(myList.get(0));//数组地址值 5 System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException 6 int [] array=(int[]) myList.get(0); 7 System.out.println(array[0]);//1
当传入一个原生数据类型数组时,Arrays.asList()
的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。
我们使用包装类型数组就可以解决这个问题。
Integer[] myArray = { 1, 2, 3 };
使用集合的修改方法:add()
、remove()
、clear()
会抛出异常。
List myList = Arrays.asList(1, 2, 3); myList.add(4);//运行时报错:UnsupportedOperationException myList.remove(1);//运行时报错:UnsupportedOperationException myList.clear();//运行时报错:UnsupportedOperationException
Arrays.asList()
方法返回的并不是 java.util.ArrayList
,而是 java.util.Arrays
的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法
List myList = Arrays.asList(1, 2, 3); System.out.println(myList.getClass());//class java.util.Arrays$ArrayList
下图是java.util.Arrays$ArrayList
的简易源码,我们可以看到这个类重写的方法有哪些。
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { ... @Override public E get(int index) { ... } @Override public E set(int index, E element) { ... } @Override public int indexOf(Object o) { ... } @Override public boolean contains(Object o) { ... } @Override public void forEach(Consumer<? super E> action) { ... } @Override public void replaceAll(UnaryOperator<E> operator) { ... } @Override public void sort(Comparator<? super E> c) { ... } }
我们再看一下java.util.AbstractList
的remove()
方法,这样我们就明白为啥会抛出UnsupportedOperationException
。
public E remove(int index) { throw new UnsupportedOperationException(); }
2.1.4. 如何正确的将数组转换为ArrayList?
1. 自己动手实现(教育目的)
//JDK1.5+ static <T> List<T> arrayToList(final T[] array) { final List<T> l = new ArrayList<T>(array.length); for (final T s : array) { l.add(s); } return (l); }
Integer [] myArray = { 1, 2, 3 };
System.out.println(arrayToList(myArray).getClass());//class java.util.ArrayList
2. 最简便的方法(推荐)
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
3. 使用 Java8 的Stream(推荐)
Integer [] myArray = { 1, 2, 3 }; List myList = Arrays.stream(myArray).collect(Collectors.toList()); //基本类型也可以实现转换(依赖boxed的装箱操作) int [] myArray2 = { 1, 2, 3 }; List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());
4. 使用 Guava(推荐)
对于不可变集合,你可以使用ImmutableList类及其of()与copyOf()工厂方法:(参数不能为空)
List<String> il = ImmutableList.of("string", "elements"); // from varargs List<String> il = ImmutableList.copyOf(aStringArray); // from array
对于可变集合,你可以使用Lists
类及其newArrayList()
工厂方法:
List<String> l1 = Lists.newArrayList(anotherListOrCollection); // from collection List<String> l2 = Lists.newArrayList(aStringArray); // from array List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs
2.2. Collection.toArray()方法使用的坑&如何反转数组
该方法是一个泛型方法:<T> T[] toArray(T[] a); 如果toArray方法中没有传递任何参数的话返回的是Object类型数组。
String [] s= new String[]{ "dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A" }; List<String> list = Arrays.asList(s); Collections.reverse(list); s=list.toArray(new String[0]);//没有指定类型的话会报错
由于JVM优化,new String[0]作为Collection.toArray()方法的参数现在使用更好,new String[0]就是起一个模板的作用,指定了返回数组的类型,0是为了节省空间,因为它只是为了说明返回的类型。详见:https://shipilev.net/blog/2016/arrays-wisdom-ancients/
2.3. 不要在 foreach 循环里进行元素的 remove/add 操作
如果要进行remove操作,可以调用迭代器的 remove方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add方法,迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。
fail-fast 机制 :多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。
java.util包下面的所有的集合类都是fail-fast的,而java.util.concurrent包下面的所有的类都是fail-safe的。