samples/gc/test/org/apidesign/gc/CompilerSurprisesTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sun, 06 Oct 2013 22:05:14 +0200
changeset 407 e1439046d96e
parent 288 0f2e5a6ddbe5
permissions -rw-r--r--
Looks like scala change URLs of its releases
     1 package org.apidesign.gc;
     2 
     3 import java.lang.ref.Reference;
     4 import java.lang.ref.WeakReference;
     5 import org.junit.Test;
     6 import org.netbeans.junit.NbTestCase;
     7 import static org.junit.Assert.*;
     8 
     9 // BEGIN: compiler.surprises.intro
    10 public class CompilerSurprisesTest {
    11     Reference<String> cache;
    12 
    13     public String factory() {
    14         String value = new String("Can I disappear?");
    15         cache = new WeakReference<String>(value);
    16         return value;
    17     }
    18 
    19     @Test
    20     public void checkThatTheValueCanDisapper() {
    21         String retValue = factory();
    22         retValue = null;
    23         assertGC("Nobody holds the string value anymore." +
    24                 "It can be GCed.", cache);
    25     }
    26 // FINISH: compiler.surprises.intro
    27 
    28 // BEGIN: compiler.surprises.error
    29     @Test
    30     public void obviouslyWithoutClearingTheReferenceItCannotBeGCed() {
    31         String retValue = factory();
    32 // commented out:        retValue = null;
    33         assertNotGC("The reference is still on stack." +
    34                 "It cannot be GCed.", cache);
    35     }
    36 // END: compiler.surprises.error
    37 
    38 
    39 // BEGIN: compiler.surprises.surprise
    40     boolean yes = true;
    41     @Test
    42     public void canItBeGCedSurprisingly() {
    43         String retValue;
    44         if (yes) {
    45             retValue = factory();
    46         }
    47         assertGC("Can be GCed, as retValue is not on stack!!!!", cache);
    48     }
    49 // END: compiler.surprises.surprise
    50 
    51 
    52 // BEGIN: compiler.surprises.fix
    53     boolean ok = true;
    54     @Test
    55     public void canItBeGCedIfInitialized() {
    56         String retValue = null;
    57         if (ok) {
    58             retValue = factory();
    59         }
    60         assertNotGC("Cannot be GCed as retValue is not stack", cache);
    61     }
    62 // END: compiler.surprises.fix
    63 
    64 // BEGIN: compiler.surprises.fix.init
    65     @Test public void properInitializationFixesTheProblem() {
    66         String retValue;
    67         if (yes) {
    68             retValue = factory();
    69         } else {
    70             retValue = null;
    71         }
    72         assertNotGC("Cannot be GCed, now the retValue is on stack", cache);
    73     }
    74 // END: compiler.surprises.fix.init
    75 
    76 // BEGIN: compiler.surprises.fix.final
    77     @Test public void properUseOfFinalFixesTheProblem() {
    78         final String retValue;
    79         if (yes) {
    80             retValue = factory();
    81         } else {
    82             retValue = null;
    83         }
    84         assertNotGC("Cannot be GCed, now the retValue is on stack", cache);
    85     }
    86 // END: compiler.surprises.fix.final
    87 
    88 // BEGIN: compiler.surprises.scope
    89     @Test public void canItBeHeldByNoLongerExistingScopeSurprisingly() {
    90         {
    91             Object val = factory();
    92         }
    93         assertNotGC("Surprisingly this variable cannot be GCed, " +
    94                 "even val is out of scope!!!!", cache);
    95     }
    96 // END: compiler.surprises.scope
    97 
    98     private static void assertGC(String msg, Reference<?> ref) {
    99         NbTestCase.assertGC(msg, ref);
   100     }
   101 
   102     private static void assertNotGC(String msg, Reference<?> ref) {
   103         try {
   104             NbTestCase.assertGC("Cannot be GCed. " + msg, ref);
   105         } catch (Error ex) {
   106             // OK
   107             return;
   108         }
   109         fail(msg + ref.get());
   110     }
   111 }