1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.Constructor; 18 import java.lang.reflect.Field; 19 import java.lang.reflect.Method; 20 import java.lang.reflect.Modifier; 21 import java.util.Arrays; 22 23 public class Reflection { canDiscoverWithGetDeclaredField(Class<?> klass, String name)24 public static boolean canDiscoverWithGetDeclaredField(Class<?> klass, String name) { 25 try { 26 klass.getDeclaredField(name); 27 return true; 28 } catch (NoSuchFieldException ex) { 29 return false; 30 } 31 } 32 canDiscoverWithGetDeclaredFields(Class<?> klass, String name)33 public static boolean canDiscoverWithGetDeclaredFields(Class<?> klass, String name) { 34 for (Field f : klass.getDeclaredFields()) { 35 if (f.getName().equals(name)) { 36 return true; 37 } 38 } 39 return false; 40 } 41 canDiscoverWithGetField(Class<?> klass, String name)42 public static boolean canDiscoverWithGetField(Class<?> klass, String name) { 43 try { 44 klass.getField(name); 45 return true; 46 } catch (NoSuchFieldException ex) { 47 return false; 48 } 49 } 50 canDiscoverWithGetFields(Class<?> klass, String name)51 public static boolean canDiscoverWithGetFields(Class<?> klass, String name) { 52 for (Field f : klass.getFields()) { 53 if (f.getName().equals(name)) { 54 return true; 55 } 56 } 57 return false; 58 } 59 canGetField(Class<?> klass, String name)60 public static boolean canGetField(Class<?> klass, String name) { 61 try { 62 Field f = klass.getDeclaredField(name); 63 f.setAccessible(true); 64 f.getInt(Modifier.isStatic(f.getModifiers()) ? null : klass.newInstance()); 65 return true; 66 } catch (Exception ex) { 67 ex.printStackTrace(); 68 return false; 69 } 70 } 71 canSetField(Class<?> klass, String name)72 public static boolean canSetField(Class<?> klass, String name) { 73 try { 74 Field f = klass.getDeclaredField(name); 75 f.setAccessible(true); 76 f.setInt(Modifier.isStatic(f.getModifiers()) ? null : klass.newInstance(), 42); 77 return true; 78 } catch (Exception ex) { 79 ex.printStackTrace(); 80 return false; 81 } 82 } 83 canDiscoverWithGetDeclaredMethod(Class<?> klass, String name)84 public static boolean canDiscoverWithGetDeclaredMethod(Class<?> klass, String name) { 85 try { 86 klass.getDeclaredMethod(name); 87 return true; 88 } catch (NoSuchMethodException ex) { 89 return false; 90 } 91 } 92 canDiscoverWithGetDeclaredMethods(Class<?> klass, String name)93 public static boolean canDiscoverWithGetDeclaredMethods(Class<?> klass, String name) { 94 for (Method m : klass.getDeclaredMethods()) { 95 if (m.getName().equals(name)) { 96 return true; 97 } 98 } 99 return false; 100 } 101 canDiscoverWithGetMethod(Class<?> klass, String name)102 public static boolean canDiscoverWithGetMethod(Class<?> klass, String name) { 103 try { 104 klass.getMethod(name); 105 return true; 106 } catch (NoSuchMethodException ex) { 107 return false; 108 } 109 } 110 canDiscoverWithGetMethods(Class<?> klass, String name)111 public static boolean canDiscoverWithGetMethods(Class<?> klass, String name) { 112 for (Method m : klass.getMethods()) { 113 if (m.getName().equals(name)) { 114 return true; 115 } 116 } 117 return false; 118 } 119 canInvokeMethod(Class<?> klass, String name)120 public static boolean canInvokeMethod(Class<?> klass, String name) { 121 try { 122 Method m = klass.getDeclaredMethod(name); 123 m.setAccessible(true); 124 m.invoke(klass.isInterface() ? null : klass.newInstance()); 125 return true; 126 } catch (Exception ex) { 127 ex.printStackTrace(); 128 return false; 129 } 130 } 131 canDiscoverWithGetDeclaredConstructor(Class<?> klass, Class<?> args[])132 public static boolean canDiscoverWithGetDeclaredConstructor(Class<?> klass, Class<?> args[]) { 133 try { 134 klass.getDeclaredConstructor(args); 135 return true; 136 } catch (NoSuchMethodException ex) { 137 return false; 138 } 139 } 140 canDiscoverWithGetDeclaredConstructors(Class<?> klass, Class<?> args[])141 public static boolean canDiscoverWithGetDeclaredConstructors(Class<?> klass, Class<?> args[]) { 142 for (Constructor c : klass.getDeclaredConstructors()) { 143 if (Arrays.equals(c.getParameterTypes(), args)) { 144 return true; 145 } 146 } 147 return false; 148 } 149 canDiscoverWithGetConstructor(Class<?> klass, Class<?> args[])150 public static boolean canDiscoverWithGetConstructor(Class<?> klass, Class<?> args[]) { 151 try { 152 klass.getConstructor(args); 153 return true; 154 } catch (NoSuchMethodException ex) { 155 return false; 156 } 157 } 158 canDiscoverWithGetConstructors(Class<?> klass, Class<?> args[])159 public static boolean canDiscoverWithGetConstructors(Class<?> klass, Class<?> args[]) { 160 for (Constructor c : klass.getConstructors()) { 161 if (Arrays.equals(c.getParameterTypes(), args)) { 162 return true; 163 } 164 } 165 return false; 166 } 167 canInvokeConstructor(Class<?> klass, Class<?> args[], Object[] initargs)168 public static boolean canInvokeConstructor(Class<?> klass, Class<?> args[], Object[] initargs) { 169 try { 170 Constructor c = klass.getDeclaredConstructor(args); 171 c.setAccessible(true); 172 c.newInstance(initargs); 173 return true; 174 } catch (Exception ex) { 175 ex.printStackTrace(); 176 return false; 177 } 178 } 179 canUseNewInstance(Class<?> klass)180 public static boolean canUseNewInstance(Class<?> klass) throws IllegalAccessException { 181 try { 182 klass.newInstance(); 183 return true; 184 } catch (InstantiationException ex) { 185 return false; 186 } 187 } 188 getHiddenApiAccessFlags()189 private static native int getHiddenApiAccessFlags(); 190 canObserveFieldHiddenAccessFlags(Class<?> klass, String name)191 public static boolean canObserveFieldHiddenAccessFlags(Class<?> klass, String name) 192 throws Exception { 193 return (klass.getDeclaredField(name).getModifiers() & getHiddenApiAccessFlags()) != 0; 194 } 195 canObserveMethodHiddenAccessFlags(Class<?> klass, String name)196 public static boolean canObserveMethodHiddenAccessFlags(Class<?> klass, String name) 197 throws Exception { 198 return (klass.getDeclaredMethod(name).getModifiers() & getHiddenApiAccessFlags()) != 0; 199 } 200 canObserveConstructorHiddenAccessFlags(Class<?> klass, Class<?> args[])201 public static boolean canObserveConstructorHiddenAccessFlags(Class<?> klass, Class<?> args[]) 202 throws Exception { 203 return (klass.getConstructor(args).getModifiers() & getHiddenApiAccessFlags()) != 0; 204 } 205 } 206