Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Prochaines sessions inter-entreprises : 28-31 mars 2017 / 13-16 juin 2017
Sessions intra-entreprises sur demande.
Inscrivez-vous vite !

Java Quiz #40

To please your Project Manager, a former developer (yeaaars ago), you sometimes let him help you develop some "very important" parts of your application.

Today, he's in charge of displaying "Hello World" by iterating on a list containing those words. Alas, distracted by his going on vacation this very afternoon, he forgets to add "World" to the list before starting the iteration. Trying to correct his mistake, he adds it a few lines later, but now his code unexpectedly breaks down at runtime ("this must be a JVM bug !").

A few minutes before leaving, he asks you to find a solution in his absence, with the following instructions :

  • Do not modify his existing code, it's Perfect (of course).
  • The FIXME tag shows where you're allowed to insert your corrective code
  • He must be able to understand your solution when he comes back (so

using Reflection is not an option).

Are you worth the trust of your beloved Manager ?

  1. final List<String> list = new ArrayList<String>() {{ add("Hello"); }};
  2. final Iterator<String> iterator = list.iterator();
  3. System.out.println(iterator.next());
  4. list.add("World");
  5. // FIXME : work here while I'm sunbathing
  6. System.out.println(iterator.next());

Hints - Keep in mind that :

  • the iterator is declared final
  • this is only a code fragment, so you cannot use System.exit(0) or return; you wouldn't like your application to terminate prematurely, would you ?
  • since you cannot modify the existing code, you cannot delete or ignore the last line, which must print "World"

Note : I must thank Romain Revol for helping me to write this quiz. Romain successfully attended the "Heinz Kabutz's Java Specialist Master Course" training session I presented in France in June at Zenika's office.



Answer :
Well, this is unusual. Since Steen gave the most detailed (and correct) answer I've ever seen on this blog (see comment 45 below), I will simply paste it here as the official answer.
Congratulations, Steen :)

When running:

java -cp . ManagersHello

We get :

Hello
Exception in thread "main" java.util.ConcurrentModificationException
  at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
  at java.util.AbstractList$Itr.next(AbstractList.java:343)
  at ManagersHello.main(ManagersHello.java:146)

The javadoc for ConcurrentModificationException says:

If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

The AbstractList class provides the Iterator that is used in the ArrayList, and this class has an internal class Itr that uses two field to detect whether there has been made 'structural modifications' to the subject of the iteration.

The field "int expectedModCount" is initiated to be equal to the field "protected transient int modCount = 0;", and modCount keeps track of the structural modifications. If modCount at some points in the iteration does not equal expectedModCount, a ConcurrentModificationException is thrown.
Such a check is made on most calls on the Iterator, which is implemented using the Itr inner class.

In the code below, the assertation holds until the second call to iterator.next() is made, because at that time, the expectedModCount is 0, while the modCount of the list is 1.

The call "list.add("World");" will increment the modCount after the list has been structurally changed. This means that the first call to the check method after this statement will throw a ConcurrentModificationException.

This window can be used to try to modify the modCount of the list instance so that it will again be equal to expectedModCount before the iterator.next() method is called. Since modCount is an int, an overflow will wrap the value from Integet.MAX_VALUE to Integer.MIN_VALUE and therefore it will be possible to reach the value of expectedModCount through an integer overflow.

In the ArrayList implementation, which is the instantiated type of the field list in the code, 4 methods change the variable modCount upon invocation :

  • public void trimToSize()
  • public void ensureCapacity(int minCapacity)
  • public E remove(int index)
  • public void clear()

trimToSize will increase the modification count by one and then check to see if the number of elements in an internal array buffer is smaller the number of elements specified in the construction of the ArrayList. If this is the case, an invokation of Arrays.copyOf(T original, int newLength) is made.

ensureCapacity will likewise increase the modification count and the perform a check on whether the specified minimum capacity is larger than the number of elements currently in the ArrayList.

remove will do a range check, increase the modification count and remove the element E at the specified index.

clear will increase the modification count and then remove (nullify) all elements in the ArrayList

Starting from the bottom, neither the clear() nor the remove() methods will work in this scenario, since their structural modification will be to remove the very element we wish to print. Using clear() will make the second call to iterator.next() fail with a NoSuchElementException. Using remove(int) will make the second call to ((ArrayList)list).remove(0) fail with an IndexOutOfBoundsException, since there is no more elements to remove and hence none at index 0.

Of course, calling remove(0) for uneven numbers (except Integer.MIN_VALUE) and subsequently add("World") (for even numbers) will work, as the list will end up on the correct modification count and the correct number of elements ("World") at the end of the for loop.

This leaves us with ensureCapacity(int) and trimToSize(), both of which will work, because they preserve the elements in the list.

  1. public class Quiz40 {
  2.  
  3. public static void main(String[] args) {
  4. final List<String> list = new ArrayList<String>() {{
  5. add("Hello");
  6. }};
  7. final Iterator<String> iterator = list.iterator();
  8. System.out.println(iterator.next());
  9. list.add("World");
  10. // FIXME : work here while I'm sunbathing
  11.  
  12. for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
  13. //solution_one
  14. ((ArrayList) list).ensureCapacity(1);
  15.  
  16. //solution_two
  17. ((ArrayList) list).trimToSize();
  18.  
  19. //solution_three
  20. if (!(i == Integer.MIN_VALUE) && !(i % 2 == 0)) {
  21. ((ArrayList) list).remove(0);
  22. }
  23. if (i % 2 == 0) {
  24. list.add("World");
  25. }
  26. }
  27.  
  28. System.out.println(iterator.next());
  29. }
  30.  
  31. }

Commentaires

1. Le jeudi 29 juillet 2010, 02:57 par Mathieu

Le but est de faire un overflow sur modCount. La méthode trimToSize est a priori la plus rapide car ne fait presque aucune opération quand la liste ne change pas, sauf augmenter modCount

ArrayList al = (ArrayList) list;
for (int n = Integer.MIN_VALUE; n < Integer.MAX_VALUE; n++) al.trimToSize();

Et si vous voulez formaté tel que demandé, lancer le code suivant avec "java -Dline.separator= Main"

System.out.print(" ");
ArrayList al = (ArrayList) list;
for (int n = Integer.MIN_VALUE; n < Integer.MAX_VALUE; n++) al.trimToSize();

2. Le jeudi 29 juillet 2010, 09:20 par Alexius Diakogiannis

Ok I thing I got it
@@
//First of all lets put stuff in a new Iterator so we can work with
Iterator newIter = list.iterator();
//Take the Hello String and remove it
newIter.next();
newIter.remove();
//Print the world String
System.out.println(newIter.next().toString());
//Stop the iterator from continuing
while(iterator.hasNext())
@@

3. Le jeudi 29 juillet 2010, 09:47 par Olivier Croisier

@Alexius : Interesting solution, though not the one I expected.
Now try again, but using only the existing iterator.

4. Le jeudi 29 juillet 2010, 10:52 par Jérôme

Bon, je suis sûr que ce n'est pas ce que tu as en tête, je n'utilise ni la liste ni l'iterator, mais même le chef de projet qui a codé pour la dernière fois en VB 1.0 devrait comprendre :

System.out.println("World"); if(false)

En plus, les perfs sont bonnes :)

5. Le jeudi 29 juillet 2010, 11:00 par Alexius Diakogiannis

@Jerome LoL I love it!!!!!
@Olivier
How about this?

list.remove("Hello");
System.out.println(list.get(0));
while(iterator.hasNext())

6. Le jeudi 29 juillet 2010, 12:04 par Hikage

Bon, vu que notre CP n'est surement pas adapte de l'optimisation, ce code lui permet de faire le travail et de prendre un bon café :

final Iterator<String> iterator = list.iterator();



System.out.println(iterator.next());
list.add("World");

/* FIX */
((ArrayList)list).trimToSize();



for( int j = 0 ;j< Integer.MAX_VALUE ; j++){
((ArrayList)list).trimToSize();
((ArrayList)list).trimToSize();
}
/* END FIX */

System.out.println(iterator.next());

7. Le jeudi 29 juillet 2010, 12:05 par Jérôme

Another solution, highly dependent on the internals of ArrayList. An integer overflow is used to "reset" the internal modification counter.

for(int i=0;i!=-1;i++) ((ArrayList)list).ensureCapacity(0);

It takes around 30 seconds on my computer to run, I hope this code is not called too often.

8. Le jeudi 29 juillet 2010, 12:06 par Ptitourson

Je fais faire un ptit tour au modCount interne de l'array list histoire qu'il revienne à sa valeur attendue :)

L'exception survient lorsque le modCount de la liste (nombre de modifications de la liste) est différent de l'expectedModCount de l'itérateur (nombre de modifications de la liste à la création de l'itérateur).

Dans notre cas : expectedModCount = 1 et le modCount = 2 (apres l'ajout de "World").

Chaque modification de la liste incrémente le modCount, je l'incrémente donc jusqu'à ce qu'il revienne sur sa valeur initiale (=1) en appelant la méthode trimToSize(), qui ne consomme presque rien en CPU, autant de fois que nécessaire :

// FIXME : insert some magic code here
ArrayList<String> list2 = (ArrayList<String>) list;
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {

 list2.trimToSize(); // modCount incremented

}
// modCount back to 1!

9. Le jeudi 29 juillet 2010, 12:10 par Jérôme

Wahou, 3 fois la même solution en 3 minutes...

10. Le jeudi 29 juillet 2010, 12:47 par Olivier Croisier

Bon les gars, ça va pas du tout, vous êtes trop forts, les quizz tiennent de moins en moins longtemps !
(Mention spéciale pour Mathieu qui a répondu à 3h du mat' :)

11. Le jeudi 29 juillet 2010, 12:54 par Jérôme

Ça, en postant tes quiz à 1 heure du matin aussi, ça favorise pas les masses laborieuses qui se lèvent tôt pour aller travailler en France ;)

12. Le jeudi 29 juillet 2010, 23:38 par Mathieu

Non ca favorise ceux qui sont à Montréal (Canada) ;-)

13. Le vendredi 30 juillet 2010, 08:15 par Alexius Diakogiannis

Hi mate,
I think you blog has a bug regarding the timestamp!
I was the fisrt to answer (and as a metter of fact twice) but suddenly I have the seccond entry! :P

Maybe next time you should think of making a Blog in JAVA and not in php! :)

Would you like your Greek affiliates to host it for you?

ps When you will be visiting Greece to stop by from Zenika Hellas offices?

cheers!

14. Le vendredi 30 juillet 2010, 10:48 par Olivier Croisier

@Alexius : this is not a bug :)
Mathieu answered just a couple hours after I published the quiz, so I hid it to keep you guys searching by yourselves. When I saw everyone got it right, I just displayed Mathieu's comment again.

15. Le vendredi 30 juillet 2010, 16:43 par Yogesh Sinha

long tt = 2147483647L + 2147483647L + 1;
for(long i=0; i<tt; i++) {

 list.add("");

}

This would make the modCount variable in AbstractList equal to 1. calling iterator.next() would not satisfy the condition for checkForComodification() function and "World" would be printed.
I could not test it as I don't have enough memory to allocate to JVM.

16. Le vendredi 30 juillet 2010, 17:34 par da.futt

The trouble with all the solutions involving the modCount field is that they violate the third requirement, to wit, that the bugger is supposed to understand it. How on earth would he be able to, if doesn't know the contract of java.util.Iterator and thinks a ConcurrentModificationException is a JVM bug?

Jérôme's first solution (#4) is the only correct one posted so far, per requirements.

17. Le vendredi 30 juillet 2010, 17:39 par finnw

@Alexius, I think your version can still throw a ConcurrentModificationException from iterator.hasNext() (it might be implementation-dependent)

18. Le vendredi 30 juillet 2010, 17:40 par dd

// FIXME : work here while I'm sunbathing
iterator = list.iterator();
iterator.next();
System.err.println(iterator.next());

19. Le vendredi 30 juillet 2010, 18:28 par lapsus63

Pareil que dd, j'aurais simplement dit :
(iterator = list.iterator()).next();

20. Le vendredi 30 juillet 2010, 18:44 par tori

Hi,
very nice riddle - but which answer does the author meant?

21. Le vendredi 30 juillet 2010, 19:00 par Olivier Croisier

@dd & @lapsus63 : the iterator variable is declared "final", so your code wouldn't compile.
@Yogesh Sinha : you could alternatively add and remove items in the list, instead of keeping adding only ; this would eliminate the memory consumption issue, and still increment the modcount.

22. Le vendredi 30 juillet 2010, 19:21 par vimil

final List<String> list = new ArrayList() add("Hello"); ;
final Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
list.add("World");
System.out.println(list.get(1));
if(lis.size(0 ==0)
System.out.println(iterator.next());

23. Le vendredi 30 juillet 2010, 20:45 par Brad

Can someone explain why this works. Is the modCount value changing? Also I was playing with the loop and noticed:
for (int n = Integer.MIN_VALUE; n < Integer.MAX_VALUE-1; n++) al.trimToSize();
doesn't work but
for (int n = Integer.MIN_VALUE; n < Integer.MAX_VALUE; n++) al.trimToSize();
does. What is the trick to looping through the complete range of Integer?

24. Le vendredi 30 juillet 2010, 21:02 par szafir

// Run with -Dline.separator=" " to avoid the line break, but you get an extra space at the end.
// FIXME BEGIN
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
((ArrayList<String>) list).trimToSize();
}
// FIXME END

25. Le vendredi 30 juillet 2010, 22:14 par Sebastian

// FIXME : work here while I'm sunbathing
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){

@Override
public void uncaughtException(Thread t, Throwable e) {
}
});
System.out.println("World");

26. Le vendredi 30 juillet 2010, 23:35 par Mike

System.out.println("World");
System.exit(0);

27. Le samedi 31 juillet 2010, 11:50 par Alexius Diakogiannis

@finnw
No it will not mate because it does not actually move the pointer but just checks if it can be moved :)
@Brad
Yes I would like to know why too! :)

28. Le samedi 31 juillet 2010, 19:25 par vizier

The trick is to overflow the modCount variable, so that ConcurrentModificationException is not thrown.

modCount is incremented in each modifying method of ArrayList (add, addAll, clear, etc.), and checked in the methods of the Iterator implementations ( next(), etc.). So by overflowing and in a sense restarting the modCount, we can make sure that modCount is the same as before even after we call add() on the list.

@Brad
In adition to the above explanation, let me give another example. If we need to add two strings to the list (instead of one), we would loop one less, in order to satisfy the equality in that case. I guess this clarifies the case.

29. Le samedi 31 juillet 2010, 23:19 par Gary

Interesting problem. I had a go, and came up with this - it's very hacky, but takes less time to complete!

// FIXME : work here while I'm sunbathing
try {
System.out.println(iterator.next());
} catch (ConcurrentModificationException cme) {
System.out.println(list.get(1));
}

30. Le samedi 31 juillet 2010, 23:50 par Gary

Interesting problem. I had a go, and came up with this - it's very hacky, but takes less time to complete!

try {
System.out.println(iterator.next());
} catch (ConcurrentModificationException cme) {
System.out.println(list.get(1));
}

31. Le dimanche 1 août 2010, 05:33 par Bala

// FIXME : work here while I'm sunbathing

System.out.println(list.listIterator(1).next());

32. Le dimanche 1 août 2010, 06:14 par Kishore Senji

I know the following is not the correct answer. However just for fun.

// FIXME : insert some magic code here
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
if(e instanceof ConcurrentModificationException) {
System.out.println(list.get(1));
}
}
});

33. Le dimanche 1 août 2010, 20:20 par Al

System.out.println(list.get(1));

if (1 == 0)

34. Le lundi 2 août 2010, 01:00 par Planet Coke

Try these lines:

@@

       Iterator<String> iterator2 = list.iterator();
       iterator2.next();
       _invoke(iterator2);
   }
   private static void _invoke(Iterator iterator ) {

@@

35. Le lundi 2 août 2010, 22:12 par Pavlov

Interesting ideas! Maybe the easiest way is simply:

iterator = list.listIterator(1);

36. Le lundi 2 août 2010, 23:28 par Planet Coke

keep in mind, that the iterator reference was declared final.

37. Le mardi 3 août 2010, 07:18 par Raveesha Joshi

// FIXME : work here while I'm sunbathing
list.remove(0);
System.out.println(list.iterator().next());

38. Le mardi 3 août 2010, 09:54 par Olivier Croisier

Many interesting ideas here, but also many wrong answers.
Keep in mind that :
- the iterator is declared final, so you cannot do iterator = list.iterator();
- this is only a code fragment, so you cannot use System.exit(0) or return; you wouldn't like your application to terminate prematurely.
- since you cannot modify the existing code, you cannot delete or ignore the last line, which performs iterator.next() and therefore triggers a ConcurrentModificationException

Have fun :)

39. Le mardi 3 août 2010, 10:24 par Abbas

public static void main(String args) {
final List<String> list = new ArrayList<String>() add("Hello"); ;

final Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
list.add("World");
System.out.println(list.get(list.size()-1));}} class TheLinesFollowsThisCalssIsNotUsed{{Iterator iterator = null;
System.out.println(iterator.next());

}

40. Le mardi 3 août 2010, 10:26 par Abbas


final List<String> list = new ArrayList<String>() add("Hello"); ;

final Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
list.add("World");
System.out.println(list.get(list.size()-1));}} class TheLinesFollowsThisCalssIsNotUsed{{Iterator iterator = null;
System.out.println(iterator.next());

41. Le mardi 3 août 2010, 10:31 par zazzo

...

// FIXME : work here while I'm sunbathing

new Runnable(){
public void run(){
try {
Field f = iterator.getClass().getDeclaredField("expectedModCount");
f.setAccessible(true);
f.setInt(iterator, 2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.run();

// FIXME : work here while I'm sunbathing
System.out.println(iterator.next());

42. Le mardi 3 août 2010, 11:10 par Bozho

ArrayList<String> list2 = (ArrayList<String>) list;
for (long i = 0; i < Integer.MAX_VALUE * 2l + 1; i ++) {

      list2.trimToSize();

}

43. Le mardi 3 août 2010, 13:20 par zazzo

ehm... sorry... i haven't read the third condition line :-(

44. Le mardi 3 août 2010, 16:25 par Michael

Easy and simple:

final List<String> list = new ArrayList() add("Hello"); ;
final Iterator<String> iterator = list.iterator();
System.out.println(iterator.next());
list.add("World");
System.out.println("World");
if (0)
System.out.println(iterator.next());

45. Le mardi 3 août 2010, 21:22 par Steen

Sorry for the verbosity. Please delete this post if it is deemed unsuitably long:
<code>
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

/*

* 
* Warnings produced when compiling this class
*
* ManagersHello.java:116: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList
*       final List<String> list = new ArrayList() {{ add("Hello"); }};
*                                                       ^
* ManagersHello.java:116: warning: [unchecked] unchecked conversion
* found   : <anonymous java.util.ArrayList>
* required: java.util.List<java.lang.String>
*       final List<String> list = new ArrayList() {{ add("Hello"); }};
*                                 ^
*
* When running:
*
* java -cp . ManagersHello
* Hello
* Exception in thread "main" java.util.ConcurrentModificationException
*  at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
*  at java.util.AbstractList$Itr.next(AbstractList.java:343)
*  at ManagersHello.main(ManagersHello.java:146)
* 
* The javadoc for ConcurrentModificationException says:
*
* If a single thread issues a sequence of method invocations that
* violates the contract of an object, the object may throw this
* exception. For example, if a thread modifies a collection directly
* while it is iterating over the collection with a fail-fast iterator,
* the iterator will throw this exception.
*
* The AbstractList class provides the Iterator that is used in the
* ArrayList, and this class has an internal class Itr that uses two
* field to detect whether there has been made 'structural
* modifications' to the subject of the iteration.
*
* The field `int expectedModCount` is initiated to be equal to the
* field `protected transient int modCount = 0;` and modCount keeps
* track of the structural modifications. If modCount at some points
* in the iteration does not equal expectedModCount, a
* ConcurrentModificationException is thrown.
* 
* Such a check is made on most calls on the Iterator, which is
* implemented using the Itr inner class
*
* In the code below, the assertation holds until the second call to
* `iterator.next()` is made, because at that time, the
* expectedModCount is 0, while the modCount of the List is 1.
*
* the call `list.add("World");` will increment the modCount _after_
* the list has been structurally changed. This means that the first
* call to the check method after this statement will throw a
* ConcurrentModificationException.
*
* This window can be used to try to modify the modCount of the list
* instance so that it will again be equal to expectedModCount
* _before_ the iterator.next() method is called. Since modCount is an
* int, an overflow will wrap the value from Integet.MAX_VALUE to
* Integer.MIN_VALUE and therefore it will be possible to reach the
* value of expectedModCount through an integer overflow.
*
* In the ArrayList implementation, which is the instantiated type of
* the field `list` in the code below, xx methods change the variable
* modCount upon invocation:
*
* - public void trimToSize()
* - public void ensureCapacity(int minCapacity)
* - public E remove(int index)
* - public void clear()
*
* trimToSize will increase the modification count by one and then
* check to see if the number of elements in an internal array buffer
* is smaller the number of elements specified in the construction of
* the ArrayList. If this is the case, an invokation of
* `Arrays.copyOf(T[] original, int newLength)` is made.
*
* ensureCapacity will likewise increase the modification count and
* the perform a check on whether the specified minimum capacity is
* larger than the number of elements currently in the ArrayList.
*
* remove will do a range check, increase the modification count and
* remove the element E at the specified index
*
* clear will increase the modification count and then remove
* (nullify) all elements in the ArrayList
*
* Starting from the bottom, neither the clear nor the remove methods
* will work in this scenario, since their structural modification
* will be to remove the very element we wish to print. Using clear()
* will make the second call to iterator.next() fail with a
* NoSuchElementException. Using remove(int) will make the second call
* to ((ArrayList)list).remove(0) fail with an
* IndexOutOfBoundsException, since there is no more elements to
* remove and hence none at index 0.  
* 
* Of course, calling remove(0) for uneven numbers (except
* Integer.MIN_VALUE) and subsequently add( "World" ) (for even
* numbers) will work, as the list will end up on the correct
* modification count _and_ the correct number of elements ( "World" )
* at the end of the for loop.
*
*
* This leaves us with ensureCapacity(int) and trimToSize(), both of
* which will work, because they preserve the elements in the list
*
*/

public class ManagersHello
{

   public static void main( String[] args )
   {
       final List<String> list = new ArrayList() {{ add("Hello"); }};
       final Iterator<String> iterator = list.iterator();
       System.out.println(iterator.next());
       list.add("World");
       // FIXME : work here while I'm sunbathing
       newly_inserted_code:
       {
           for( int i=Integer.MIN_VALUE;i<Integer.MAX_VALUE;i++)
           {
               solution_one:
               {
                   // ((ArrayList)list).ensureCapacity(1);
               }
               solution_two:
               {
                   // ((ArrayList)list).trimToSize();
               }
               solution_three:
               {
                   if( ! ( i == Integer.MIN_VALUE ) && ! ( i%2 == 0 ) )
                   {
                       ((ArrayList)list).remove(0);
                   }
                   if( i%2 == 0 )
                   {
                       ((ArrayList)list).add("World");
                   }
               }
           }
       }
       System.out.println(iterator.next());
   }

}
</code>

46. Le mardi 3 août 2010, 21:31 par Olivier Croisier

This must be the most complete solution to one of my quizzes I've ever seen O_O
And it works !
Nice job !

47. Le mercredi 4 août 2010, 08:23 par Fanie Deysel

@@
// FIXME : work here while I'm sunbathing
try {
Field f = iterator.getClass().getDeclaredField("expectedModCount");
f.setAccessible(true);
f.setInt(iterator, 2);
} catch (Exception e) {}
// FIXME : work here while I'm sunbathing
@@

48. Le mercredi 4 août 2010, 08:27 par Fanie Deysel

@@

// FIXME : work here while I'm sunbathing
try {
Field f = iterator.getClass().getDeclaredField("expectedModCount");
f.setAccessible(true);
f.setInt(iterator, list.size());
} catch (Exception e) {}
// FIXME : work here while I'm sunbathing

@@

49. Le samedi 4 septembre 2010, 11:50 par Roshan

Please elaborate more on this statment :
"Since modCount is an int, an overflow will wrap the value from Integet.MAX_VALUE to Integer.MIN_VALUE and therefore it will be possible to reach the value of expectedModCount through an integer overflow. "
How it is working ?

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.