1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  *
   8  *   - Redistributions of source code must retain the above copyright
   9  *     notice, this list of conditions and the following disclaimer.
  10  *
  11  *   - Redistributions in binary form must reproduce the above copyright
  12  *     notice, this list of conditions and the following disclaimer in the
  13  *     documentation and/or other materials provided with the distribution.
  14  *
  15  *   - Neither the name of Oracle nor the names of its
  16  *     contributors may be used to endorse or promote products derived
  17  *     from this software without specific prior written permission.
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.reflect.Method;
  34 import java.util.Arrays;
  35 
  36 /**
  37  * The code sample illustrates changes in the reflection API linked
  38  * <b>default methods</b>. Since Java SE 8, a new method is added into the class
  39  * <b><code>java.lang.reflect.Method</code></b>, with which you can
  40  * reflectively determine whether or not a default method provided by an
  41  * interface (<b><code>Method.isDefault()</code></b>).
  42  *
  43  * @author Taras Ledkov
  44  */
  45 public class Reflection {
  46 
  47     /**
  48      * Base interface to illustrate the new reflection API.
  49      *
  50      * @see Dog
  51      */
  52     public interface Animal {
  53 
  54         /**
  55          * Return string representation of the eat action for Animal
  56          *
  57          * @return string representation of the eat action for Animal
  58          */
  59         default String eat() {
  60             return this.getClass().getSimpleName()
  61                     + " eats like an ordinary animal";
  62         }
  63 
  64         /**
  65          * Return string representation of the sleep action for Animal
  66          *
  67          * @return string representation of the sleep action for Animal
  68          */
  69         default String sleep() {
  70             return this.getClass().getSimpleName()
  71                     + " sleeps like an ordinary animal";
  72         }
  73 
  74         /**
  75          * Return string representation of the go action for Animal
  76          *
  77          * @return string representation of the go action for Animal
  78          */
  79         String go();
  80     }
  81 
  82     /**
  83      * Dog class to illustrate the new reflection API. You can see that:
  84      * <ul>
  85      * <li> the {@link #go} and {@link #sleep} methods are not default.
  86      * {@link #go} is not the default implementation and the {@link #sleep} method
  87      * implementation wins as subtype (according with {@link Inheritance} rule.
  88      * 2) </li>
  89      * <li> the {@link #eat} is a simple default method that is not overridden 
  90      * in this class.
  91      * </li>
  92      * </ul>
  93      */
  94     public static class Dog implements Animal {
  95 
  96         /**
  97          * Return string representation of the go action for Dog
  98          *
  99          * @return string representation of the go action for Dog
 100          */
 101         @Override
 102         public String go() {
 103             return "Dog walks on four legs";
 104         }
 105 
 106         /**
 107          * Return string representation of the sleep action for Dog
 108          *
 109          * @return string representation of the sleep action for Dog
 110          */
 111         @Override
 112         public String sleep() {
 113             return "Dog sleeps";
 114         }
 115     }
 116 
 117     /**
 118      * Illustrate the usage of the method java.lang.reflect.Method.isDefault()
 119      *
 120      * @param args command-line arguments
 121      * @throws NoSuchMethodException internal demo error
 122      */
 123     public static void main(final String[] args) throws NoSuchMethodException {
 124         Method[] methods = {
 125             Dog.class.getMethod("eat"),
 126             Dog.class.getMethod("go"),
 127             Dog.class.getMethod("sleep")};
 128         final Dog dog = new Dog();
 129 
 130         Arrays.asList(methods).stream().forEach((m) -> {
 131             System.out.println("Method name:   " + m.getName());
 132             System.out.println("    isDefault: " + m.isDefault());
 133             System.out.print("    invoke:    ");
 134             try {
 135                 System.out.print(m.invoke(dog));
 136             } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
 137             }
 138             System.out.println();
 139         });
 140     }
 141 }