// Potential security hole! public static final Thing[] VALUES = { ... }; // 方案1 private static final Thing[] PRIVATE_VALUES = { ... }; public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES)) ; // 方案2 private static final Thing[] PRIVATE_VALUES = { ... }; public static final Thing[] values() { return PRIVATE_VALUES.clone(); }
// Degenerate classes like this should not be public! class Point { public double x; public double y; } // Encapsulation of data by accessor methods and mutators class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } }
// Immutable complex number class public final class Complex { private final double re; private final double im; public Complex(double re, double im) { this.re = re; this.im = im; } public double realPart() { return re; } public double imaginaryPart() { return im; } // plus表明相加返回新的對象,函數式編程,狀態不可變。 // add表明相加返回this對象,命令式編程,狀態可變。 public Complex plus(Complex c) { return new Complex(re + c.re, im + c.im); } public Complex minus(Complex c) { return new Complex(re - c.re, im - c.im); } public Complex times(Complex c) { return new Complex(re * c.re - im * c.im, re * c.im + im * c.re); } public Complex dividedBy(Complex c) { double tmp = c.re * c.re + c.im * c.im; return new Complex((re * c.re + im * c.im) / tmp, (im * c.re - re * c.im) / tmp); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Complex)) return false; Complex c = (Complex) o; // See page 47 to find out why we use compare instead of == return Double.compare(c.re, re) == 0 && Double.compare(c.im, im) == 0; } @Override public int hashCode() { return 31 * Double.hashCode(re) + Double.hashCode(im); } @Override public String toString() { return "(" + re + " + " + im + "i)"; } }
public class InstrumentedHashSet<E> extends HashSet<E> { // The number of attempted element insertions private int addCount = 0; public InstrumentedHashSet() { } public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } } // jdk7 InstrumentedHashSet<String> s = new InstrumentedHashSet<>(); s.addAll(Arrays.asList({"Snap", "Crackle", "Pop"})); // 結果爲3 // jdk9 InstrumentedHashSet<String> s = new InstrumentedHashSet<>(); s.addAll(Arrays.asList({"Snap", "Crackle", "Pop"})); // 結果爲6 // jdk升級後,HashSet內部addAll方法依賴於add方法
// 包裝類:裝飾者模式 public class InstrumentedSet<E> extends ForwardingSet<E> { private int addCount = 0; public InstrumentedSet(Set<E> s) { super(s); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } } // 轉發類:組合模式 // Reusable forwarding class public class ForwardingSet<E> implements Set<E> { private final Set<E> s; public ForwardingSet(Set<E> s) { this.s = s; } public void clear() { s.clear(); } public boolean contains(Object o) { return s.contains(o); } public boolean isEmpty() { return s.isEmpty(); } public int size() { return s.size(); } public Iterator<E> iterator() { return s.iterator(); } public boolean add(E e) { return s.add(e); } public boolean remove(Object o) { return s.remove(o); } public boolean containsAll(Collection<?> c) { return s.containsAll(c); } public boolean addAll(Collection<? extends E> c) { return s.addAll(c); } public boolean removeAll(Collection<?> c) { return s.removeAll(c); } public boolean retainAll(Collection<?> c) { return s.retainAll(c); } public Object[] toArray() { return s.toArray(); } public <T> T[] toArray(T[] a) { return s.toArray(a); } @Override public boolean equals(Object o) { return s.equals(o); } @Override public int hashCode() { return s.hashCode(); } @Override public String toString() { return s.toString(); } }
經過包裝者類模式,使用接口使得安全地加強類的功能成爲可能。html
混合模式demojava
public interface Singer { AudioClip sing(Song s); } public interface Songwriter { Song compose(int chartPosition); } // 既是歌手又是做曲人 public interface SingerSongwriter extends Singer, Songwriter { AudioClip strum(); void actSensitive(); }
public interface Interface { public static int test = 0; public static void publicTest() { privateTest(); } private static void privateTest() { System.out.println(test); } public default void defaultTest() { System.out.println("defaultTest"); } public abstract void abstractTest(); } public class InterfaceImpl implements Interface { public void extendTest() { defaultTest(); } @Override public void abstractTest() { System.out.println("abstractTest"); } public static void main(String[] args) { InterfaceImpl extend = new InterfaceImpl(); extend.extendTest(); extend.defaultTest(); System.out.println(Interface.test); Interface.publicTest(); } }
模板實現類在基本接口方法上實現剩餘的非基本接口方法(模板方法模式)。編程
demo1:繼承模板類數組
// AbstractList是模板類,基於它能夠很是容易實現新的類 // 適配器模式:int[] -> List<Integer> static List<Integer> intArrayAsList(int[] a) { Objects.requireNonNull(a); return new AbstractList<>() { @Override public Integer get(int i) { return a[i]; } @Override public Integer set(int i, Integer val) { int oldVal = a[i]; a[i] = val; return oldVal; } @Override public int size() { return a.length; } }; }
// Map.Entry最主要的兩個方法:getKey和getValue(必需實現) setValue(可選,只有可修改的Map才須要實現) // hashCode、equals和toString方法能夠由模板類提供默認實現 public abstract class AbstractMapEntry<K,V> implements Map.Entry<K,V> { // Entries in a modifiable map must override this method @Override public V setValue(V value) { throw new UnsupportedOperationException(); } // Implements the general contract of Map.Entry.equals @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry) o; return Objects.equals(e.getKey(), getKey()) && Objects.equals(e.getValue(), getValue()); } // Implements the general contract of Map.Entry.hashCode @Override public int hashCode() { return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); } @Override public String toString() { return getKey() + "=" + getValue(); } }
public interface PhysicalConstants { static final double AVOGADROS_NUMBER = 6.022_140_857e23; static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23; static final double ELECTRON_MASS = 9.109_383_56e-31; }
public class PhysicalConstants { private PhysicalConstants() { } // Prevents instantiation public static final double AVOGADROS_NUMBER = 6.022_140_857e23; public static final double BOLTZMANN_CONST =1.380_648_52e-23; public static final double ELECTRON_MASS = 9.109_383_56e-31; }
class Figure { enum Shape { RECTANGLE, CIRCLE }; // Tag field - the shape of this figure final Shape shape; // These fields are used only if shape is RECTANGLE double length; double width; // This field is used only if shape is CIRCLE double radius; // Constructor for circle Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // Constructor for rectangle Figure(double length, double width) { shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area() { switch(shape) { case RECTANGLE: return length * width; case CIRCLE: return Math.PI * (radius * radius); default: throw new AssertionError(shape); } } }
abstract class Figure { abstract double area(); } class Circle extends Figure { final double radius; Circle(double radius) { this.radius = radius; } @Override double area() { return Math.PI * (radius * radius); } } class Rectangle extends Figure { final double length; final double width; Rectangle(double length, double width) { this.length = length; this.width = width; } @Override double area() { return length * width; } }
public class Calculator{ public static enum Operation{ PLUS,MINUS; } }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>{ static class Node<K,V> implements Map.Entry<K,V>{} }
public class OuterClass { private static int outTest = 1; public static class InnerClass { private int inTest; public void test() { System.out.println(outTest); } } public static void main(String[] args) { InnerClass innerClass = new OuterClass.InnerClass(); innerClass.test(); } }
// 如:List -> Iterator public class MySet<E> extends AbstractSet<E> { // Bulk of the class omitted @Override public Iterator<E> iterator() { return new MyIterator(); } private class MyIterator implements Iterator<E> { } }
public class OuterClass { private int outTest = 1; public class InnerClass { private int inTest; public void test() { System.out.println(outTest); // System.out.println(OuterClass.this.outTest); } public OuterClass getOuterClass(){ return OuterClass.this; } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); InnerClass innerClass = outerClass.new InnerClass(); innerClass.test(); } }
public static void main(String[] args) { try(AutoCloseable myCloseable = new AutoCloseable() { @Override public void close() { System.out.println("close success!"); } };) { System.out.println("use myCloseable"); } catch (Exception e) { e.printStackTrace(); } }
public static void main(String[] args) { class A{ private int test = 1; }; A a = new A(); System.out.println(a.test);; }
參考:緩存