home | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (KeyTest.java)

This example Java source code file (KeyTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

alldefaults, annotation, atomicreference, bindingannotation, class, configurationexception, guice, key, list, marker, reflection, retention, runnable, typeliteral, util, weakreference

The KeyTest.java Java example source code

/**
 * Copyright (C) 2006 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.inject;

import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.assertEqualsBothWays;
import static com.google.inject.Asserts.assertNotSerializable;
import static com.google.inject.Asserts.awaitClear;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.google.inject.spi.Dependency;
import com.google.inject.util.Types;

import junit.framework.TestCase;

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author crazybob@google.com (Bob Lee)
 */
public class KeyTest extends TestCase {

  public void foo(List<String> a, List b) {}
  public void bar(Provider<List a) {}
  @Foo String baz;
  List<? extends CharSequence> wildcardExtends;

  public void testOfType() {
    Key<Object> k = Key.get(Object.class, Foo.class);
    Key<Integer> ki = k.ofType(Integer.class);
    assertEquals(Integer.class, ki.getRawType());
    assertEquals(Foo.class, ki.getAnnotationType());
  }

  public void testKeyEquality() {
    Key<List a = new Key>(Foo.class) {};
    Key<List b = Key.get(new TypeLiteral>() {}, Foo.class);
    assertEqualsBothWays(a, b);
  }

  public void testProviderKey() throws NoSuchMethodException {
    Key<?> actual = Key.get(getClass().getMethod("foo", List.class, List.class)
        .getGenericParameterTypes()[0]).providerKey();
    Key<?> expected = Key.get(getClass().getMethod("bar", Provider.class)
        .getGenericParameterTypes()[0]);
    assertEqualsBothWays(expected, actual);
    assertEquals(expected.toString(), actual.toString());
  }

  public void testTypeEquality() throws Exception {
    Method m = getClass().getMethod("foo", List.class, List.class);
    Type[] types = m.getGenericParameterTypes();
    assertEquals(types[0], types[1]);
    Key<List k = new Key>() {};
    assertEquals(types[0], k.getTypeLiteral().getType());
    assertFalse(types[0].equals(
        new Key<List() {}.getTypeLiteral().getType()));
  }

  /**
   * Key canonicalizes {@link int.class} to {@code Integer.class}, and
   * won't expose wrapper types.
   */
  public void testPrimitivesAndWrappersAreEqual() {
    Class[] primitives = new Class[] {
        boolean.class, byte.class, short.class, int.class, long.class,
        float.class, double.class, char.class, void.class
    };
    Class[] wrappers = new Class[] {
        Boolean.class, Byte.class, Short.class, Integer.class, Long.class,
        Float.class, Double.class, Character.class, Void.class
    };

    for (int t = 0; t < primitives.length; t++) {
      @SuppressWarnings("unchecked")
      Key primitiveKey = Key.get(primitives[t]);
      @SuppressWarnings("unchecked")
      Key wrapperKey = Key.get(wrappers[t]);

      assertEquals(primitiveKey, wrapperKey);
      assertEquals(wrappers[t], primitiveKey.getRawType());
      assertEquals(wrappers[t], wrapperKey.getRawType());
      assertEquals(wrappers[t], primitiveKey.getTypeLiteral().getType());
      assertEquals(wrappers[t], wrapperKey.getTypeLiteral().getType());
    }

    Key<Integer> integerKey = Key.get(Integer.class);
    Key<Integer> integerKey2 = Key.get(Integer.class, Named.class);
    Key<Integer> integerKey3 = Key.get(Integer.class, Names.named("int"));

    Class<Integer> intClassLiteral = int.class;
    assertEquals(integerKey, Key.get(intClassLiteral));
    assertEquals(integerKey2, Key.get(intClassLiteral, Named.class));
    assertEquals(integerKey3, Key.get(intClassLiteral, Names.named("int")));

    Type intType = int.class;
    assertEquals(integerKey, Key.get(intType));
    assertEquals(integerKey2, Key.get(intType, Named.class));
    assertEquals(integerKey3, Key.get(intType, Names.named("int")));

    TypeLiteral<Integer> intTypeLiteral = TypeLiteral.get(int.class);
    assertEquals(integerKey, Key.get(intTypeLiteral));
    assertEquals(integerKey2, Key.get(intTypeLiteral, Named.class));
    assertEquals(integerKey3, Key.get(intTypeLiteral, Names.named("int")));
  }

  public void testSerialization() throws IOException, NoSuchFieldException {
    assertNotSerializable(Key.get(B.class));
    assertNotSerializable(Key.get(B.class, Names.named("bee")));
    assertNotSerializable(Key.get(B.class, Named.class));
    assertNotSerializable(Key.get(B[].class));
    assertNotSerializable(Key.get(new TypeLiteral<Map>() {}));
    assertNotSerializable(Key.get(new TypeLiteral<List() {}));
    assertNotSerializable(Key.get(Types.listOf(Types.subtypeOf(CharSequence.class))));
  }

  public void testEqualityOfAnnotationTypesAndInstances() throws NoSuchFieldException {
    Foo instance = getClass().getDeclaredField("baz").getAnnotation(Foo.class);
    Key<String> keyWithInstance = Key.get(String.class, instance);
    Key<String> keyWithLiteral = Key.get(String.class, Foo.class);
    assertEqualsBothWays(keyWithInstance, keyWithLiteral);
  }

  public void testNonBindingAnnotationOnKey() {
    try {
      Key.get(String.class, Deprecated.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertContains(expected.getMessage(), "java.lang.Deprecated is not a binding annotation. ",
          "Please annotate it with @BindingAnnotation.");
    }
  }

  public void testBindingAnnotationWithoutRuntimeRetention() {
    try {
      Key.get(String.class, Bar.class);
      fail();
    } catch (IllegalArgumentException expected) {
      assertContains(expected.getMessage(), Bar.class.getName() + " is not retained at runtime.",
          "Please annotate it with @Retention(RUNTIME).");
    }
  }

  <T> void parameterizedWithVariable(List typeWithVariables) {}

  /** Test for issue 186 */
  public void testCannotCreateKeysWithTypeVariables() throws NoSuchMethodException {
    ParameterizedType listOfTType = (ParameterizedType) getClass().getDeclaredMethod(
        "parameterizedWithVariable", List.class).getGenericParameterTypes()[0];

    TypeLiteral<?> listOfT = TypeLiteral.get(listOfTType);
    try {
      Key.get(listOfT);
      fail("Guice should not allow keys for java.util.List<T>");
    } catch (ConfigurationException e) {
      assertContains(e.getMessage(),
          "java.util.List<T> cannot be used as a key; It is not fully specified.");
    }

    TypeVariable tType = (TypeVariable) listOfTType.getActualTypeArguments()[0];
    TypeLiteral<?> t = TypeLiteral.get(tType);
    try {
      Key.get(t);
      fail("Guice should not allow keys for T");
    } catch (ConfigurationException e) {
      assertContains(e.getMessage(),
          "T cannot be used as a key; It is not fully specified.");
    }
  }

  public void testCannotGetKeyWithUnspecifiedTypeVariables() {
    TypeLiteral<Integer> typeLiteral = KeyTest.createTypeLiteral();
    try {
      Key.get(typeLiteral);
      fail("Guice should not allow keys for T");
    } catch (ConfigurationException e) {
      assertContains(e.getMessage(),
          "T cannot be used as a key; It is not fully specified.");
    }
  }

  private static <T> TypeLiteral createTypeLiteral() {
    return new TypeLiteral<T>() {};
  }

  public void testCannotCreateKeySubclassesWithUnspecifiedTypeVariables() {
    try {
      KeyTest.<Integer>createKey();
      fail("Guice should not allow keys for T");
    } catch (ConfigurationException e) {
      assertContains(e.getMessage(),
          "T cannot be used as a key; It is not fully specified.");
    }
  }

  private static <T> Key createKey() {
    return new Key<T>() {};
  }

  interface B {}

  @Retention(RUNTIME)
  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
  @BindingAnnotation @interface Foo {}

  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
  @BindingAnnotation @interface Bar {}

  class HasTypeParameters<A, B extends List {
    A a; B b; C c;
  }

  public void testKeysWithDefaultAnnotations() {
    AllDefaults allDefaults = HasAnnotations.class.getAnnotation(AllDefaults.class);
    assertEquals(Key.get(Foo.class, allDefaults), Key.get(Foo.class, AllDefaults.class));

    Marker marker = HasAnnotations.class.getAnnotation(Marker.class);
    assertEquals(Key.get(Foo.class, marker), Key.get(Foo.class, Marker.class));

    Key<?> noDefaults = Key.get(Foo.class, NoDefaults.class);
    assertNull(noDefaults.getAnnotation());
    assertEquals(NoDefaults.class, noDefaults.getAnnotationType());

    Key<?> someDefaults = Key.get(Foo.class, SomeDefaults.class);
    assertNull(someDefaults.getAnnotation());
    assertEquals(SomeDefaults.class, someDefaults.getAnnotationType());
  }

  @Retention(RUNTIME)
  @BindingAnnotation @interface AllDefaults {
    int v1() default 1;
    String v2() default "foo";
  }

  @Retention(RUNTIME)
  @BindingAnnotation @interface SomeDefaults {
    int v1() default 1;
    String v2() default "foo";
    Class<?> clazz();
  }

  @Retention(RUNTIME)
  @BindingAnnotation @interface NoDefaults {
    int value();
  }

  @Retention(RUNTIME)
  @BindingAnnotation @interface Marker {
  }

  @AllDefaults
  @Marker
  class HasAnnotations {}

  public void testAnonymousClassesDontHoldRefs() {
    final AtomicReference<Provider> stringProvider =
        new AtomicReference<Provider>();
    final AtomicReference<Provider> intProvider =
        new AtomicReference<Provider>();
    final Object foo = new Object() {
      @SuppressWarnings("unused") @Inject List<String> list;
    };
    Module module = new AbstractModule() {
      @Override protected void configure() {
        bind(new Key<List() {}).toInstance(new ArrayList());
        bind(new TypeLiteral<List() {}).toInstance(new ArrayList());

        stringProvider.set(getProvider(new Key<List() {}));
        intProvider.set(binder().getProvider(Dependency.get(new Key<List() {})));

        binder().requestInjection(new TypeLiteral<Object>() {}, foo);
      }
    };
    WeakReference<Module> moduleRef = new WeakReference(module);
    final Injector injector = Guice.createInjector(module);
    module = null;
    awaitClear(moduleRef); // Make sure anonymous keys & typeliterals don't hold the module.

    Runnable runner = new Runnable() {
      @Override public void run() {
        injector.getInstance(new Key<Typed() {});
        injector.getInstance(Key.get(new TypeLiteral<Typed() {}));
      }
    };
    WeakReference<Runnable> runnerRef = new WeakReference(runner);
    runner.run();
    runner = null;
    awaitClear(runnerRef); // also make sure anonymous keys & typeliterals don't hold for JITs
  }

  static class Typed<T> {}

}

Other Java examples (source code examples)

Here is a short list of links related to this Java KeyTest.java source code file:



my book on functional programming

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.