/**
* Returns a BigInteger whose value is (this mod m). This method
* differs from the remainder method in that it always returns a
* non-negative BigInteger.
*
* @param m the modulus, which must be positive
* @return this mod m
* @throws ArithmeticException if m is less than or equal to 0
*/publicBigIntegermod(BigInteger m){if(m.signum()<=0)thrownewArithmeticException("Modulus <= 0: "+ m);...// Do the computation}
publicfinalclassPeriod{privatefinalDate start;privatefinalDate end;/**
* @param start the beginning of the period
* @param end the end of the period; must not precede start
* @throws IllegalArgumentException if start is after end
* @throws NullPointerException if start or end is null
*/publicPeriod(Date start,Date end){if(start.compareTo(end)>0)thrownewIllegalArgumentException(start +" after "+ end);this.start = start;this.end = end;}publicDatestart(){return start;}publicDateend(){return end;}...// Remainder omitted}
Date start =newDate();Date end =newDate();Period p =newPeriod(start, end);
end.setYear(78);// Modifies internals of p!
從Java 8 開始,解決此問(wèn)題的顯而易?的方法是使用 Instant(或LocalDateTime 或 ZonedDateTime)代替Date,因?yàn)樗麄兪遣豢勺兊?。?code>Date在老代碼里仍有使用的地方,為了保護(hù) Period 實(shí)例的內(nèi)部不受這種攻擊,可以使用拷?來(lái)做 Period 實(shí)例的組件:
publicPeriod(Date start,Date end){this.start =newDate(start.getTime());this.end =newDate(end.getTime());if(this.start.compareTo(this.end)>0)thrownewIllegalArgumentException(this.start +" after "+this.end);}
上面的分析帶來(lái)的啟發(fā)是:應(yīng)該盡量使用不可變對(duì)象作為對(duì)象內(nèi)部的組件,這樣就不必?fù)?dān)心保護(hù)性拷?,。在 Period 示例中,使用Instant(或LocalDateTime或ZonedDateTime)。另一個(gè)選項(xiàng)是存儲(chǔ)Date.getTime() 返回的long類型來(lái)代替Date引用,。
publicclassSetList{publicstaticvoidmain(String[] args){Set<Integer> set =newTreeSet<>();List<Integer> list =newArrayList<>();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);}System.out.println(set +" "+ list);}}
staticintmin(int... args){if(args.length ==0)thrownewIllegalArgumentException("Too few arguments");int min = args[0];for(int i =1; i < args.length; i++)if(args[i]< min)
min = args[i];return min;}
privatefinalList<Cheese> cheesesInStock =...;/**
* @return a list containing all of the cheeses in the shop,
* or null if no cheeses are available for purchase.
*/publicList<Cheese>getCheeses(){return cheesesInStock.isEmpty()?null:newArrayList<>(cheesesInStock);}
publicstatic<EextendsComparable<E>>Emax(Collection<E> c){if(c.isEmpty())thrownewIllegalArgumentException("Empty collection");E result =null;for(E e : c)if(result ==null|| e.compareTo(result)>0)
result =Objects.requireNonNull(e);return result;}
publicstatic<EextendsComparable<E>>Optional<E>max(Collection<E> c){if(c.isEmpty())returnOptional.empty();E result =null;for(E e : c)if(result ==null|| e.compareTo(result)>0)
result =Objects.requireNonNull(e);returnOptional.of(result);}
/**
* Returns the element at the specified position in this list.
*
* <p>This method is <i>not</i> guaranteed to run in constant
* time. In some implementations it may run in time proportional
* to the element position.
*
* @param index index of element to return; must be
* non-negative and less than the size of this list
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= this.size()})
*/Eget(int index);
/**
* Returns true if this collection is empty.
*
* @implSpec
* This implementation returns {@code this.size() == 0}.
*
* @return true if this collection is empty
*/publicbooleanisEmpty(){...}
包含HTML元字符的文檔,例如小于號(hào)(<),大于號(hào)(>)和 and 符號(hào)(&),是用{@literal}標(biāo)簽將它們包圍起來(lái):
注意概要描述是否包含句點(diǎn),例如以「A college degree, such as B.S., M.S. or Ph.D.」會(huì)導(dǎo)致概要描述為「A college degree, such as B.S., M.S」,??s寫「M.S.」中的第二個(gè)句號(hào)后面跟著一個(gè)空格。最好的解決方案是用{@literal}標(biāo)簽
/**
* A college degree, such as B.S., {@literal M.S.} or Ph.D.
*/publicclassDegree{...}
/**
* An object that maps keys to values. A map cannot contain
* duplicate keys; each key can map to at most one value.
*
* (Remainder omitted)
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/publicinterfaceMap<K,V>{...}
在記錄枚舉類型時(shí),一定要記錄常量:
/**
* An instrument section of a symphony orchestra.
*/publicenumOrchestraSection{/** Woodwinds, such as flute, clarinet, and oboe. */
WOODWIND,/** Brass instruments, such as french horn and trumpet. */
BRASS,/** Percussion instruments, such as timpani and cymbals. */
PERCUSSION,/** Stringed instruments, such as violin and cello. */
STRING;}
在為注解類型記錄文檔時(shí),一定要記錄任何成員:
/**
* Indicates that the annotated method is a test method that
* must throw the designated exception to pass.
*/@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceExceptionTest{/**
* The exception that the annotated test method must throw
* in order to pass. (The test is permitted to throw any
* subtype of the type described by this class object.)
*/Class<?extendsThrowable>value();}