对于想了解JavaReflection设置属性的读者,本文将是一篇不可错过的文章,我们将详细介绍javareflections,并且为您提供关于com.badlogic.gdx.utils.refle
对于想了解Java Reflection设置属性的读者,本文将是一篇不可错过的文章,我们将详细介绍java reflections,并且为您提供关于com.badlogic.gdx.utils.reflect.ReflectionException的实例源码、io.grpc.reflection.v1alpha.ServerReflectionRequest的实例源码、Java Reflection、Java Reflection Beans属性API的有价值信息。
本文目录一览:- Java Reflection设置属性(java reflections)
- com.badlogic.gdx.utils.reflect.ReflectionException的实例源码
- io.grpc.reflection.v1alpha.ServerReflectionRequest的实例源码
- Java Reflection
- Java Reflection Beans属性API
Java Reflection设置属性(java reflections)
我有一个具有许多可设置/可获取的属性的类。我想使用 反射 来设置这些属性,但是我对实现有两个问题
这是我班上的一些简化代码
class Q { public String question_1; public String question_2; public String question_3; public String answer_1; public String answer_2; public String answer_3; //etc. etc. Many String attributes // … constructor and other stuff are omitted // here is my method for "dynamically" setting each attribute public void set_attribute(String a_raw_string, String my_field) { try { Class cls = Class.forName("com.xyz.models.Q"); Field fld = cls.getField(my_field); fld.set(this, a_raw_string); } catch (Throwable e) { System.err.println(e); }}
然后,我像这样设置各个字段:
Q q = new Q();q.set_attribute("abcde", "question_1");q.set_attribute("defgh", "question_2");// etc.
这有效(即,当我调用set_attribute时设置实例变量。
但是,它们仅在实例变量被声明为public时起作用。当它们被声明为私有时,我得到一个 NoSuchFieldException
问题1: 当字段为私有时,为什么会出现该错误?我的天真假设是,由于set_attribute函数是类的一部分,因此它应该可以不受限制地访问实例变量。
问题2:
我认为我可能对这个问题有过多的想法(即,我不应该使用反射来设置变量)。是否有更推荐的方法?我之所以要使用反射,是因为要声明大量的setter方法非常麻烦……所以我想知道是否有人以更好的方式解决了这种烦恼。
谢谢!
答案1
小编典典我想我可能对此想法太想了(即,我不应该以这种方式使用反射来设置变量)
是的
反射是相当缓慢的,仅应作为最后的手段。如果只是为了避免有太多冗余代码,请考虑使用自动代码生成。对于纯数据对象,我强烈建议您使用协议缓冲区;它将生成getters
/ setters(您只需要声明字段)。另外,它还允许在C ++,Java和Python之间轻松进行数据通信。
如果您有一个具有很多字段但又不是纯数据对象的类…那么
- 您应该考虑所有字段是否应该都是可变的。(您真的需要二传手吗?)
- 字段是否应该可见。(您是否需要任何访问器?)
通常,将字段设为“最终”,在构造函数中对其进行初始化,并且不提供任何访问权限或通过已实现的接口提供有限的访问权限,通常是一个好主意。
com.badlogic.gdx.utils.reflect.ReflectionException的实例源码
@Override public Object read(ByteBuffer byteBuffer) { try { byte id = byteBuffer.get(); if(id == -2){ return FrameworkSerializer.read(byteBuffer); }else { Class<?> type = Registrator.getByID(id); Packet packet = (Packet) ClassReflection.newInstance(type); packet.read(byteBuffer); return packet; } }catch (ReflectionException e){ throw new RuntimeException(e); } }
/** * Returns the Class matching the name of the JsonValue,or null if there is no match or it's nameless. */ private Class getClass(JsonValue value,ObjectMap<String,Class> tagsToClasses) { if (value.name() != null && value.name().length() > 0) { String className = value.name(); Class type = tagsToClasses.get(className); if (type == null) { try { type = ClassReflection.forName(className); } catch (ReflectionException ex) { type = null; } } return type; } return null; }
/** * Creates platform specific object by reflection. * <p> * Uses class names given by {@link #getAndroidClassName()} and {@link #getIOSClassName()} * <p> * If you need to run project on different platform use {@link #setMockObject(Object)} to polyfill platform object. * * @throws PlatformdistributorException Throws when something is wrong with environment */ @SuppressWarnings("unchecked") protected Platformdistributor() throws PlatformdistributorException { String className = null; if (Gdx.app.getType() == Application.ApplicationType.Android) { className = getAndroidClassName(); } else if (Gdx.app.getType() == Application.ApplicationType.iOS) { className = getIOSClassName(); } else if (Gdx.app.getType() == Application.ApplicationType.WebGL) { className = getWebGLClassName(); } else { return; } try { Class objClass = ClassReflection.forName(className); platformObject = (T) ClassReflection.getConstructor(objClass).newInstance(); } catch (ReflectionException e) { e.printstacktrace(); throw new PlatformdistributorException("Something wrong with environment"); } }
public void invoke(JGameObject clickTarget) { for (Component component : clickTarget.getAllComponents()) { if (component.getClass().getName().equals(invokeComponent)) { Object[] parameters = args.toArray(new Object[args.size()]); Class[] parametersType = new Class[args.size()]; for (int x = 0; x < parameters.length; x++) { parametersType[x] = parameters[x].getClass(); } try { Method method = ClassReflection.getDeclaredMethod(component.getClass(),invokeMethod,parametersType); method.invoke(component,parameters); } catch (ReflectionException e) { e.printstacktrace(); } } } }
@Override public void read(Json json,JsonValue jsonValue) { try { name = jsonValue.getString("name"); optional = jsonValue.getBoolean("optional"); if (jsonValue.get("value").isNumber()) { type = Float.TYPE; value = Double.parseDouble(jsonValue.getString("value")); } else { type = ClassReflection.forName(jsonValue.getString("type")); if (jsonValue.get("value").isNull()) { value = null; } else { value = jsonValue.getString("value"); } } } catch (ReflectionException ex) { Gdx.app.error(getClass().toString(),"Error reading from serialized object",ex); DialogFactory.showDialogErrorStatic("Read Error...","Error reading from serialized object.\n\nopen log?"); } }
@Override public void read(Json json,JsonValue jsonData) { try { colors = json.readValue("colors",Array.class,jsonData); fonts = json.readValue("fonts",jsonData); classstyleMap = new OrderedMap<>(); for (JsonValue data : jsonData.get("classstyleMap").iterator()) { classstyleMap.put(ClassReflection.forName(data.name),json.readValue(Array.class,data)); } for (Array<StyleData> styleDatas : classstyleMap.values()) { for (StyleData styleData : styleDatas) { styleData.jsonData = this; } } customClasses = json.readValue("customClasses",CustomClass.class,new Array<>(),jsonData); for (CustomClass customClass : customClasses) { customClass.setMain(main); } } catch (ReflectionException e) { Gdx.app.log(getClass().getName(),"Error parsing json data during file read",e); main.getDialogFactory().showDialogError("Error while reading file...","Error while attempting to read save file.\nPlease ensure that file is not corrupted.\n\nopen error log?"); } }
/** Clones this task to a new one. If you don't specify a clone strategy through {@link #TASK_CLONER} the new task is * instantiated via reflection and {@link #copyTo(Task)} is invoked. * @return the cloned task * @throws TaskCloneException if the task cannot be successfully cloned. */ @SuppressWarnings("unchecked") public Task<E> cloneTask () { if (TASK_CLONER != null) { try { return TASK_CLONER.cloneTask(this); } catch (Throwable t) { throw new TaskCloneException(t); } } try { Task<E> clone = copyTo(ClassReflection.newInstance(this.getClass())); clone.guard = guard == null ? null : guard.cloneTask(); return clone; } catch (ReflectionException e) { throw new TaskCloneException(e); } }
/** * Read the actions from the suppled XML element and loads them into the * supplied ActionsContainer. * * The XML element should contain children in the following format: * * <pre> * <actionClassName parameter1Name="parameter1Value" parameter2Name="parameter2Value" ... /> * </pre> * * @param ac * @param actionsElement */ @SuppressWarnings({ "unchecked" }) public static void readActions(ActionsContainer ac,Element actionsElement) { if (actionsElement != null) { for (int i = 0; i < actionsElement.getChildCount(); ++i) { Element actionElement = actionsElement.getChild(i); String implementationClassName = actionElement.getName(); implementationClassName = Action.class.getPackage().getName() + "." + StringUtil.capitalizefirstLetter(implementationClassName); try { Class<? extends Action> actionClass = (Class<? extends Action>) ClassReflection .forName(implementationClassName); Action newAction = ac.addAction(actionClass); if (newAction != null) { newAction.loadFromXML(actionElement); } } catch (ReflectionException e) { throw new GdxRuntimeException(e); } } } }
@Test @SuppressWarnings("static-access") public void androidisLoadedWithV4Fragment() { androidSetup(); Mockito.when(classReflectionMock.isAssignableFrom(activityStub.getClass(),Gdx.app.getClass())).thenReturn(false); Mockito.when(classReflectionMock.isAssignableFrom(supportFragmentStub.getClass(),Gdx.app.getClass())).thenReturn(true); try { Mockito.when(constructorMock.newInstance(activityStub,config)).thenReturn(twitteraPIStub); Mockito.when(classReflectionMock.forName("android.support.v4.app.Fragment")).thenReturn(supportFragmentStub.getClass()); Mockito.when(classReflectionMock.getmethod(supportFragmentStub.getClass(),"getActivity")).thenReturn(methodMock); Mockito.when(methodMock.invoke(Gdx.app)).thenReturn(activityStub); } catch (ReflectionException e) { } fixture = new TwitterSystem(config); assertEquals(twitteraPIStub,fixture.getTwitteraPI()); }
@Test @SuppressWarnings("static-access") public void androidisLoadedWithFragment() { androidSetup(); Mockito.when(classReflectionMock.isAssignableFrom(activityStub.getClass(),Gdx.app.getClass())).thenReturn(false); Mockito.when(classReflectionMock.isAssignableFrom(fragmentStub.getClass(),config)).thenReturn(twitteraPIStub); Mockito.when(classReflectionMock.forName("android.app.Fragment")).thenReturn(fragmentStub.getClass()); Mockito.when(classReflectionMock.getmethod(fragmentStub.getClass(),"getActivity")).thenReturn(methodMock); Mockito.when(methodMock.invoke(Gdx.app)).thenReturn(activityStub); } catch (ReflectionException e) { } fixture = new TwitterSystem(config); assertEquals(twitteraPIStub,fixture.getTwitteraPI()); }
private void tryLoadHTMLTwitteraPI() { if (Gdx.app.getType() != ApplicationType.WebGL) { Gdx.app.debug(TAG,"Skip loading gdx-twitter for HTML. Not running HTML. \n"); return; } try { final Class<?> twitterClazz = ClassReflection.forName("de.tomgrill.gdxtwitter.html.HTMLTwitteraPI"); Object twitter = ClassReflection.getConstructor(twitterClazz,TwitterConfig.class).newInstance(config); twitteraPI = (TwitteraPI) twitter; Gdx.app.debug(TAG,"gdx-twitter for HTML loaded successfully."); } catch (ReflectionException e) { Gdx.app.debug(TAG,"Error creating gdx-twitter for HTML (are the gdx-twitter **.jar files installed?). \n"); e.printstacktrace(); } }
private void tryLoadioSTWitteraPI() { if (Gdx.app.getType() != ApplicationType.iOS) { Gdx.app.debug(TAG,"Skip loading gdx-twitter for iOS. Not running iOS. \n"); return; } try { // Class<?> activityClazz = // ClassReflection.forName("com.badlogic.gdx.backends.iosrobovm.IOSApplication"); final Class<?> twitterClazz = ClassReflection.forName("de.tomgrill.gdxtwitter.ios.IOSTwitteraPI"); Object twitter = ClassReflection.getConstructor(twitterClazz,TwitterConfig.class).newInstance(config); twitteraPI = (TwitteraPI) twitter; Gdx.app.debug(TAG,"gdx-twitter for iOS loaded successfully."); } catch (ReflectionException e) { Gdx.app.debug(TAG,"Error creating gdx-twitter for iOS (are the gdx-twitter **.jar files installed?). \n"); e.printstacktrace(); } }
private void handleLazyAssetInjection(final Object component,final Field field,final Asset assetData) { if (Annotations.isNotVoid(assetData.lazyCollection())) { handleLazyAssetCollectionInjection(component,field,assetData); return; } else if (assetData.value().length != 1) { throw new GdxRuntimeException( "Lazy wrapper can contain only one asset if lazy collection type is not provided. Found multiple assets in field: " + field + " of component: " + component); } final String assetPath = assetData.value()[0]; if (!assetData.loadondemand()) { load(assetPath,assetData.type()); } try { Reflection.setFieldValue(field,component,Lazy.providedBy(new AssetProvider(this,assetPath,assetData.type(),assetData.loadondemand()))); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject lazy asset.",exception); } }
@Test public void returnAndroidGDXFacebookWhenOnAndroid_core_app_Fragment() { androidPremocking(); when(ClassReflection.isAssignableFrom(Activity.class,mockObject.getClass())).thenReturn(false); try { when(ClassReflection.forName("android.support.v4.app.Fragment")).thenReturn(null); when(ClassReflection.forName("android.app.Fragment")).thenReturn(android.app.Fragment.class); when(ClassReflection.isAssignableFrom(android.app.Fragment.class,mockObject.getClass())).thenReturn(true); when(ClassReflection.getmethod(android.app.Fragment.class,"getActivity")).thenReturn(mockMethod); when(mockMethod.invoke(mockObject)).thenReturn(mockFacebook); } catch (ReflectionException e) { e.printstacktrace(); } androidPostmocking(); facebook = GDXFacebooksystem.install(new GDXFacebookConfig()); assertTrue(facebook instanceof AndroidGDXFacebook); }
@Test public void returnIOSGDXFacebookWhenOnIOS() { Application mockApplication = mock(Application.class); when(mockApplication.getType()).thenReturn(Application.ApplicationType.iOS); Gdx.app = mockApplication; try { Constructor mockConstructor = powermockito.mock(Constructor.class); GDXFacebook mockFacebook = mock(IOSGDXFacebook.class); when(ClassReflection.forName(GDXFacebookVars.CLASSNAME_IOS)).thenReturn(IOSGDXFacebook.class); when(ClassReflection.getConstructor(IOSGDXFacebook.class,GDXFacebookConfig.class)).thenReturn(mockConstructor); when(mockConstructor.newInstance(anyObject())).thenReturn(mockFacebook); } catch (ReflectionException e) { e.printstacktrace(); } facebook = GDXFacebooksystem.install(new GDXFacebookConfig()); assertTrue(facebook instanceof IOSGDXFacebook); }
@Test public void returnDesktopGDXFacebookWhenOnDesktop() { Application mockApplication = mock(Application.class); when(mockApplication.getType()).thenReturn(Application.ApplicationType.Desktop); Gdx.app = mockApplication; try { Constructor mockConstructor = powermockito.mock(Constructor.class); GDXFacebook mockFacebook = mock(DesktopGDXFacebook.class); when(ClassReflection.forName(GDXFacebookVars.CLASSNAME_DESKTOP)).thenReturn(DesktopGDXFacebook.class); when(ClassReflection.getConstructor(DesktopGDXFacebook.class,GDXFacebookConfig.class)).thenReturn(mockConstructor); when(mockConstructor.newInstance(anyObject())).thenReturn(mockFacebook); } catch (ReflectionException e) { e.printstacktrace(); } facebook = GDXFacebooksystem.install(new GDXFacebookConfig()); assertTrue(facebook instanceof DesktopGDXFacebook); }
@Test public void returnHTMLGDXFacebookWhenOnWebGL() { Application mockApplication = mock(Application.class); when(mockApplication.getType()).thenReturn(Application.ApplicationType.WebGL); Gdx.app = mockApplication; try { Constructor mockConstructor = powermockito.mock(Constructor.class); GDXFacebook mockFacebook = mock(HTMLGDXFacebook.class); when(ClassReflection.forName(GDXFacebookVars.CLASSNAME_HTML)).thenReturn(HTMLGDXFacebook.class); when(ClassReflection.getConstructor(HTMLGDXFacebook.class,GDXFacebookConfig.class)).thenReturn(mockConstructor); when(mockConstructor.newInstance(anyObject())).thenReturn(mockFacebook); } catch (ReflectionException e) { e.printstacktrace(); } facebook = GDXFacebooksystem.install(new GDXFacebookConfig()); assertTrue(facebook instanceof HTMLGDXFacebook); }
@SuppressWarnings({ "rawtypes","unchecked" }) private void injectAssets(final AssetService assetService) { try { ObjectMap map = (ObjectMap) Reflection.getFieldValue(field,component); if (map == null) { map = GdxMaps.newObjectMap(); } for (int assetIndex = 0; assetIndex < assetPaths.length; assetIndex++) { map.put(assetKeys[assetIndex],assetService.get(assetPaths[assetIndex],assetType)); } Reflection.setFieldValue(field,map); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject map of assets into component: " + component + ".",exception); } }
public static AbstractOnDeathEffect load(Element xml) { Class<AbstractOnDeathEffect> c = ClassMap.get(xml.getName().toupperCase()); AbstractOnDeathEffect type = null; try { type = (AbstractOnDeathEffect)ClassReflection.newInstance(c); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstractSpreadStyle load(Element xml) { Class<AbstractSpreadStyle> c = ClassMap.get(xml.getName().toupperCase()); AbstractSpreadStyle type = null; try { type = (AbstractSpreadStyle)ClassReflection.newInstance(c); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstractDurationStyle load(Element xml) { Class<AbstractDurationStyle> c = ClassMap.get(xml.getName().toupperCase()); AbstractDurationStyle type = null; try { type = (AbstractDurationStyle)ClassReflection.newInstance(c); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstractTownEvent load(XmlReader.Element xml ) { Class<AbstractTownEvent> c = ClassMap.get(xml.getName().toupperCase()); AbstractTownEvent type = null; try { type = (AbstractTownEvent) ClassReflection.newInstance( c ); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstractHitType load(XmlReader.Element xml ) { Class<AbstractHitType> c = ClassMap.get(xml.getName().toupperCase()); AbstractHitType type = null; try { type = (AbstractHitType) ClassReflection.newInstance( c ); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstracttargetingType load(Element xml) { Class<AbstracttargetingType> c = ClassMap.get(xml.getName().toupperCase()); AbstracttargetingType type = null; try { type = (AbstracttargetingType)ClassReflection.newInstance(c); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
public static AbstractCostType load(Element xml) { Class<AbstractCostType> c = ClassMap.get(xml.getName().toupperCase()); AbstractCostType type = null; try { type = (AbstractCostType)ClassReflection.newInstance(c); } catch (ReflectionException e) { e.printstacktrace(); } type.parse(xml); return type; }
private static void processClassName(final Iterable<Class<? extends Annotation>> annotations,final Array<Class<?>> result,final String packageName,final String className) { if (!className.startsWith(packageName)) { return; } try { final Class<?> classtoProcess = ClassReflection.forName(className); for (final Class<? extends Annotation> annotation : annotations) { if (ClassReflection.isAnnotationPresent(classtoProcess,annotation)) { result.add(classtoProcess); return; } } } catch (final ReflectionException exception) { exception.printstacktrace(); // Unexpected. Classes should be present. } }
@SuppressWarnings({ "rawtypes","unchecked" }) private void injectAssets(final AssetService assetService) { try { ObjectSet set = (ObjectSet) Reflection.getFieldValue(field,component); if (set == null) { set = GdxSets.newSet(); } for (final String assetPath : assetPaths) { set.add(assetService.get(assetPath,set); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject set of assets into component: " + component + ".",exception); } }
private void installDesktopGDXDialogs() { if (Gdx.app.getType() != ApplicationType.Desktop) { showDebugSkipInstall(ApplicationType.Desktop.name()); return; } try { final Class<?> dialogManagerClazz = ClassReflection.forName("de.tomgrill.gdxdialogs.desktop.DesktopGDXDialogs"); Object dialogManager = ClassReflection.getConstructor(dialogManagerClazz).newInstance(); this.gdxDialogs = (GDXDialogs) dialogManager; showDebugInstallSuccessful(ApplicationType.Desktop.name()); } catch (ReflectionException e) { showErrorInstall(ApplicationType.Desktop.name(),"desktop"); e.printstacktrace(); } }
private void installHTMLGDXDialogs() { if (Gdx.app.getType() != ApplicationType.WebGL) { showDebugSkipInstall(ApplicationType.WebGL.name()); return; } try { final Class<?> dialogManagerClazz = ClassReflection.forName("de.tomgrill.gdxdialogs.html.HTMLGDXDialogs"); Object dialogManager = ClassReflection.getConstructor(dialogManagerClazz).newInstance(); this.gdxDialogs = (GDXDialogs) dialogManager; showDebugInstallSuccessful(ApplicationType.WebGL.name()); } catch (ReflectionException e) { showErrorInstall(ApplicationType.WebGL.name(),"html"); e.printstacktrace(); } }
private static Array<Class<?>> extractFromBinaries(final Iterable<Class<? extends Annotation>> annotations,final String mainPackageName,final Queue<Pair<File,Integer>> filesWithDepthsToProcess) throws ReflectionException { final Array<Class<?>> result = GdxArrays.newArray(); while (!filesWithDepthsToProcess.isEmpty()) { final Pair<File,Integer> classpathFileWithDepth = filesWithDepthsToProcess.poll(); final File classpathFile = classpathFileWithDepth.getFirst(); final int depth = classpathFileWithDepth.getSecond(); if (classpathFile.isDirectory()) { addAllChildren(filesWithDepthsToProcess,classpathFile,depth); } else { final String className = getBinaryClassName(mainPackageName,depth); if (!isFromPackage(mainPackageName,className)) { continue; } final Class<?> classtoProcess = ClassReflection.forName(className); processClass(annotations,result,classtoProcess); } } return result; }
@Override public void processField(final Field field,final LmlMacro annotation,final Object component,final Context context,final Contextinitializer initializer,final ContextDestroyer contextDestroyer) { try { final Object macroData = Reflection.getFieldValue(field,component); final LmlParser parser = interfaceService.get().getParser(); final FileType fileType = annotation.fileType(); if (macroData instanceof String) { parser.parseTemplate(Gdx.files.getFileHandle((String) macroData,fileType)); } else if (macroData instanceof String[]) { for (final String macroPath : (String[]) macroData) { parser.parseTemplate(Gdx.files.getFileHandle(macroPath,fileType)); } } else { throw new GdxRuntimeException("Invalid type of LML macro deFinition in component: " + component + ". String or String[] expected,received: " + macroData + "."); } } catch (final ReflectionException exception) { throw new GdxRuntimeException( "Unable to extract macro paths from field: " + field + " of component: " + component + ".",exception); } }
/** Invoked when all skins are loaded. Injects skin assets. * * @param interfaceService used to retrieve skins. * @return {@link OnMessage#REMOVE}. */ @SuppressWarnings("unchecked") @OnMessage(AutumnMessage.SKINS_LOADED) public boolean injectFields(final InterfaceService interfaceService) { for (final Entry<Pair<String,String>,Array<Pair<Field,Object>>> entry : fieldsToInject) { final Skin skin = interfaceService.getParser().getData().getSkin(entry.key.getSecond()); final String assetId = entry.key.getFirst(); if (skin == null) { throw new ContextinitiationException( "Unable to inject asset: " + assetId + ". UnkNown skin ID: " + entry.key.getSecond()); } for (final Pair<Field,Object> injection : entry.value) { try { Reflection.setFieldValue(injection.getFirst(),injection.getSecond(),skin.get(assetId,injection.getFirst().getType())); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject skin asset: " + assetId + " from skin: " + skin + " to field: " + injection.getFirst() + " of component: " + injection.getSecond(),exception); } } } fieldsToInject.clear(); return OnMessage.REMOVE; }
@Override public void processField(final Field field,final LmlParserSyntax annotation,final ContextDestroyer contextDestroyer) { try { final Object Syntax = Reflection.getFieldValue(field,component); if (Syntax instanceof LmlSyntax) { interfaceService.getParser().setSyntax((LmlSyntax) Syntax); } else { throw new ContextinitiationException( "LmlParserSyntax-annotated fields need to contain an instance of LmlSyntax. Found: " + Syntax + " in field: " + field + " of component: " + component); } } catch (final ReflectionException exception) { throw new ContextinitiationException( "Unable to extract LML Syntax from field: " + field + " of component: " + component,exception); } }
@SuppressWarnings({ "rawtypes",exception); } }
@SuppressWarnings({ "rawtypes","unchecked" }) private void injectAssets(final AssetService assetService) { try { Array array = (Array) Reflection.getFieldValue(field,component); if (array == null) { array = GdxArrays.newArray(); } for (final String assetPath : assetPaths) { array.add(assetService.get(assetPath,array); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject array of assets into component: " + component + ".",exception); } }
private void handleLazyAssetInjection(final Object component,exception); } }
private void handleRegularassetInjection(final Object component,final Asset assetData) { if (assetData.value().length != 1) { throw new GdxRuntimeException( "Regular fields can store only 1 asset. If the field is a collection,its type is not currently supported: only LibGDX Array,ObjectSet and ObjectMap are permitted. Regular arrays will not be supported. Found multiple assets in field: " + field + " of component: " + component); } final String assetPath = assetData.value()[0]; if (assetData.loadondemand()) { // Loaded immediately. @SuppressWarnings("unchecked") final Object asset = finishLoading(assetPath,field.getType()); try { Reflection.setFieldValue(field,asset); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject asset loaded on demand.",exception); } } else { load(assetPath,field.getType()); // Scheduled to be loaded,delayed injection. assetInjections.add(new StandardAssetInjection(field,component)); } }
@SuppressWarnings({ "rawtypes","unchecked" }) private void handleMapInjection(final Object component,final Asset assetData) { if (assetData.loadondemand()) { final String[] assetPaths = assetData.value(); final String[] assetKeys = assetData.keys().length == 0 ? assetData.value() : assetData.keys(); try { ObjectMap assets = (ObjectMap) Reflection.getFieldValue(field,component); if (assets == null) { assets = GdxMaps.newObjectMap(); } for (int assetIndex = 0; assetIndex < assetPaths.length; assetIndex++) { assets.put(assetKeys[assetIndex],finishLoading(assetPaths[assetIndex],assetData.type())); } Reflection.setFieldValue(field,assets); } catch (final ReflectionException exception) { throw new GdxRuntimeException("Unable to inject array of assets into: " + component,exception); } } else { for (final String assetPath : assetData.value()) { load(assetPath,assetData.type()); } // Scheduled to be loaded,delayed injection. assetInjections.add(new ObjectMapAssetInjection(assetData.value(),assetData.keys(),component)); } }
@Override public void processField(final Field field,final AvailableLocales annotation,final ContextDestroyer contextDestroyer) { try { final Object locales = Reflection.getFieldValue(field,component); if (locales instanceof String[]) { final String[] availableLocales = (String[]) locales; final LmlParser parser = interfaceService.getParser(); parser.getData().addArgument(annotation.viewArgumentName(),availableLocales); for (final String locale : availableLocales) { parser.getData().addActorConsumer(annotation.localeChangeMethodPrefix() + locale,new LocaleChangingAction(localeService,LocaleService.toLocale(locale))); } return; } throw new GdxRuntimeException("Invalid field annotated with @AvailableLocales in component " + component + ". Expected String[],received: " + locales + "."); } catch (final ReflectionException exception) { throw new GdxRuntimeException( "Unable to read available locales from field: " + field + " of component: " + component + ".",exception); } }
protected <View> void processLmlInjectAnnotation(final View view,final Field field) { if (Reflection.isAnnotationPresent(field,LmlInject.class)) { try { final LmlInject injectionData = Reflection.getAnnotation(field,LmlInject.class); final Class<?> injectedValueType = getLmlInjectedValueType(field,injectionData); if (LmlParser.class.equals(injectedValueType)) { // Injected type equals LmlParser - parser injection was requested: Reflection.setFieldValue(field,view,this); return; } Object value = Reflection.getFieldValue(field,view); if (value == null || injectionData.newInstance()) { value = Reflection.newInstance(injectedValueType); Reflection.setFieldValue(field,value); } // Processing field's value annotations: processViewFieldAnnotations(value); } catch (final ReflectionException exception) { throw new GdxRuntimeException( "Unable to inject value of LmlInject-annotated field: " + field + " of view: " + view,exception); } } }
io.grpc.reflection.v1alpha.ServerReflectionRequest的实例源码
private void getAllExtensions(ServerReflectionRequest request) { String type = request.getAllExtensionNumbersOfType(); Set<Integer> extensions = serverReflectionIndex.getExtensionNumbersOfType(type); if (extensions != null) { ExtensionNumberResponse.Builder builder = ExtensionNumberResponse.newBuilder() .setBaseTypeName(type) .addAllExtensionNumber(extensions); serverCallStreamObserver.onNext( ServerReflectionResponse.newBuilder() .setValidHost(request.getHost()) .setoriginalRequest(request) .setAllExtensionNumbersResponse(builder) .build()); } else { sendErrorResponse(request,Status.Code.NOT_FOUND,"Type not found."); } }
private ServerReflectionResponse createServerReflectionResponse( ServerReflectionRequest request,FileDescriptor fd) { FileDescriptorResponse.Builder fdrBuilder = FileDescriptorResponse.newBuilder(); Set<String> seenFiles = new HashSet<String>(); Queue<FileDescriptor> frontier = new arraydeque<FileDescriptor>(); seenFiles.add(fd.getName()); frontier.add(fd); while (!frontier.isEmpty()) { FileDescriptor nextFd = frontier.remove(); fdrBuilder.addFileDescriptorProto(nextFd.toProto().toByteString()); for (FileDescriptor dependencyFd : nextFd.getDependencies()) { if (!seenFiles.contains(dependencyFd.getName())) { seenFiles.add(dependencyFd.getName()); frontier.add(dependencyFd); } } } return ServerReflectionResponse.newBuilder() .setValidHost(request.getHost()) .setoriginalRequest(request) .setFileDescriptorResponse(fdrBuilder) .build(); }
@Test public void fileContainingnestedSymbol() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingSymbol("grpc.reflection.testing.nestedTypeOuter.Middle.Inner") .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( ReflectionTestDepthThreeProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); assertEquals(goldenResponse,responSEObserver.firstValue().get()); }
@Test public void allExtensionNumbersOfType() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setAllExtensionNumbersOfType("grpc.reflection.testing.ThirdLevelType") .build(); Set<Integer> goldenResponse = new HashSet<Integer>(Arrays.asList(100,101)); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); Set<Integer> extensionNumberResponseSet = new HashSet<Integer>( responSEObserver .firstValue() .get() .getAllExtensionNumbersResponse() .getExtensionNumberList()); assertEquals(goldenResponse,extensionNumberResponseSet); }
@Test public void flowControl() throws Exception { FlowControlClientResponSEObserver clientResponSEObserver = new FlowControlClientResponSEObserver(); ClientCallStreamObserver<ServerReflectionRequest> requestObserver = (ClientCallStreamObserver<ServerReflectionRequest>) stub.serverReflectionInfo(clientResponSEObserver); // ClientCalls.startCall() calls request(1) initially,so we should get an immediate response. requestObserver.onNext(flowControlRequest); assertEquals(1,clientResponSEObserver.getResponses().size()); assertEquals(flowControlGoldenResponse,clientResponSEObserver.getResponses().get(0)); // Verify we don't receive an additional response until we request it. requestObserver.onNext(flowControlRequest); assertEquals(1,clientResponSEObserver.getResponses().size()); requestObserver.request(1); assertEquals(2,clientResponSEObserver.getResponses().get(1)); requestObserver.onCompleted(); assertTrue(clientResponSEObserver.onCompleteCalled()); }
@Test public void flowControlOnCompleteWithPendingRequest() throws Exception { FlowControlClientResponSEObserver clientResponSEObserver = new FlowControlClientResponSEObserver(); ClientCallStreamObserver<ServerReflectionRequest> requestObserver = (ClientCallStreamObserver<ServerReflectionRequest>) stub.serverReflectionInfo(clientResponSEObserver); // ClientCalls.startCall() calls request(1) initially,so make additional request. requestObserver.onNext(flowControlRequest); requestObserver.onNext(flowControlRequest); requestObserver.onCompleted(); assertEquals(1,clientResponSEObserver.getResponses().size()); assertFalse(clientResponSEObserver.onCompleteCalled()); requestObserver.request(1); assertTrue(clientResponSEObserver.onCompleteCalled()); assertEquals(2,clientResponSEObserver.getResponses().get(1)); }
/** Asks the Remote Server to list its services and completes when the server responds. */ public ListenableFuture<ImmutableList<String>> listServices() { ListServicesHandler rpcHandler = new ListServicesHandler(); StreamObserver<ServerReflectionRequest> requestStream = ServerReflectionGrpc.newStub(channel) .withDeadlineAfter(LIST_RPC_DEADLINE_MS,TimeUnit.MILLISECONDS) .serverReflectionInfo(rpcHandler); return rpcHandler.start(requestStream); }
/** * Returns a {@link FileDescriptorSet} containing all the transitive dependencies of the supplied * service,as provided by the Remote Server. */ public ListenableFuture<FileDescriptorSet> lookupService(String serviceName) { LookupServiceHandler rpcHandler = new LookupServiceHandler(serviceName); StreamObserver<ServerReflectionRequest> requestStream = ServerReflectionGrpc.newStub(channel) .withDeadlineAfter(LOOKUP_RPC_DEADLINE_MS,TimeUnit.MILLISECONDS) .serverReflectionInfo(rpcHandler); return rpcHandler.start(requestStream); }
ListenableFuture<FileDescriptorSet> start( StreamObserver<ServerReflectionRequest> requestStream) { this.requestStream = requestStream; requestStream.onNext(requestForSymbol(serviceName)); ++outstandingRequests; return resultFuture; }
@Override public StreamObserver<ServerReflectionRequest> serverReflectionInfo( final StreamObserver<ServerReflectionResponse> responSEObserver) { final ServerCallStreamObserver<ServerReflectionResponse> serverCallStreamObserver = (ServerCallStreamObserver<ServerReflectionResponse>) responSEObserver; ProtoReflectionStreamObserver requestObserver = new ProtoReflectionStreamObserver(updateIndexIfNecessary(),serverCallStreamObserver); serverCallStreamObserver.setonReadyHandler(requestObserver); serverCallStreamObserver.disableAutoInboundFlowControl(); serverCallStreamObserver.request(1); return requestObserver; }
private void getFileByName(ServerReflectionRequest request) { String name = request.getFileByFilename(); FileDescriptor fd = serverReflectionIndex.getFileDescriptorByName(name); if (fd != null) { serverCallStreamObserver.onNext(createServerReflectionResponse(request,fd)); } else { sendErrorResponse(request,"File not found."); } }
private void getFileContainingSymbol(ServerReflectionRequest request) { String symbol = request.getFileContainingSymbol(); FileDescriptor fd = serverReflectionIndex.getFileDescriptorBySymbol(symbol); if (fd != null) { serverCallStreamObserver.onNext(createServerReflectionResponse(request,"Symbol not found."); } }
private void getFileByExtension(ServerReflectionRequest request) { ExtensionRequest extensionRequest = request.getFileContainingExtension(); String type = extensionRequest.getContainingType(); int extension = extensionRequest.getExtensionNumber(); FileDescriptor fd = serverReflectionIndex.getFileDescriptorByExtensionAndNumber(type,extension); if (fd != null) { serverCallStreamObserver.onNext(createServerReflectionResponse(request,"Extension not found."); } }
private void listServices(ServerReflectionRequest request) { ListServiceResponse.Builder builder = ListServiceResponse.newBuilder(); for (String serviceName : serverReflectionIndex.getServiceNames()) { builder.addService(ServiceResponse.newBuilder().setName(serviceName)); } serverCallStreamObserver.onNext( ServerReflectionResponse.newBuilder() .setValidHost(request.getHost()) .setoriginalRequest(request) .setListServicesResponse(builder) .build()); }
private void sendErrorResponse( ServerReflectionRequest request,Status.Code code,String message) { ServerReflectionResponse response = ServerReflectionResponse.newBuilder() .setValidHost(request.getHost()) .setoriginalRequest(request) .setErrorResponse( ErrorResponse.newBuilder() .setErrorCode(code.value()) .setErrorMessage(message)) .build(); serverCallStreamObserver.onNext(response); }
@Test public void fileByFilename() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileByFilename("io/grpc/reflection/testing/reflection_test_depth_three.proto") .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( ReflectionTestDepthThreeProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); assertEquals(goldenResponse,responSEObserver.firstValue().get()); }
@Test public void fileContainingSymbol() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingSymbol("grpc.reflection.testing.ReflectableService.Method") .build(); List<ByteString> goldenResponse = Arrays.asList( ReflectionTestProto.getDescriptor().toProto().toByteString(),ReflectionTestDepthTwoProto.getDescriptor().toProto().toByteString(),ReflectionTestDepthTwoAlternateProto.getDescriptor().toProto().toByteString(),ReflectionTestDepthThreeProto.getDescriptor().toProto().toByteString()); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); List<ByteString> response = responSEObserver .firstValue() .get() .getFileDescriptorResponse() .getFileDescriptorProtoList(); assertEquals(goldenResponse.size(),response.size()); assertEquals(new HashSet<ByteString>(goldenResponse),new HashSet<ByteString>(response)); }
@Test public void fileContainingExtension() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingExtension( ExtensionRequest.newBuilder() .setContainingType("grpc.reflection.testing.ThirdLevelType") .setExtensionNumber(100) .build()) .build(); List<ByteString> goldenResponse = Arrays.asList( ReflectionTestProto.getDescriptor().toProto().toByteString(),new HashSet<ByteString>(response)); }
@Test public void fileContainingnestedExtension() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingExtension( ExtensionRequest.newBuilder() .setContainingType("grpc.reflection.testing.ThirdLevelType") .setExtensionNumber(101) .build()) .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( ReflectionTestDepthTwoProto.getDescriptor().toProto().toByteString()) .addFileDescriptorProto( ReflectionTestDepthThreeProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); assertEquals(goldenResponse,responSEObserver.firstValue().get()); }
private void assertServiceResponseEquals(Set<ServiceResponse> goldenResponse) throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder().setHost(TEST_HOST).setListServices("services").build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); requestObserver.onNext(request); requestObserver.onCompleted(); List<ServiceResponse> response = responSEObserver.firstValue().get().getListServicesResponse().getServiceList(); assertEquals(goldenResponse.size(),response.size()); assertEquals(goldenResponse,new HashSet<ServiceResponse>(response)); }
ListenableFuture<ImmutableList<String>> start( StreamObserver<ServerReflectionRequest> requestStream) { this.requestStream = requestStream; requestStream.onNext(LIST_SERVICES_REQUEST); return resultFuture; }
private static ServerReflectionRequest requestForDescriptor(String name) { return ServerReflectionRequest.newBuilder() .setFileByFilename(name) .build(); }
private static ServerReflectionRequest requestForSymbol(String symbol) { return ServerReflectionRequest.newBuilder() .setFileContainingSymbol(symbol) .build(); }
@Override public void onNext(ServerReflectionRequest request) { checkState(this.request == null); this.request = checkNotNull(request); handleReflectionRequest(); }
@Test public void fileByFilenameConsistentForMutableServices() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileByFilename("io/grpc/reflection/testing/dynamic_reflection_test_depth_two.proto") .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( DynamicReflectionTestDepthTwoProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); handlerRegistry.addService(dynamicService); requestObserver.onNext(request); requestObserver.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver2 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver2 = stub.serverReflectionInfo(responSEObserver2); handlerRegistry.removeService(dynamicService); requestObserver2.onNext(request); requestObserver2.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver3 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver3 = stub.serverReflectionInfo(responSEObserver3); requestObserver3.onNext(request); requestObserver3.onCompleted(); assertEquals( ServerReflectionResponse.MessageResponseCase.ERROR_RESPONSE,responSEObserver.firstValue().get().getMessageResponseCase()); assertEquals(goldenResponse,responSEObserver2.firstValue().get()); assertEquals( ServerReflectionResponse.MessageResponseCase.ERROR_RESPONSE,responSEObserver3.firstValue().get().getMessageResponseCase()); }
@Test public void fileContainingSymbolForMutableServices() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingSymbol("grpc.reflection.testing.DynamicRequest") .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( DynamicReflectionTestDepthTwoProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); handlerRegistry.addService(dynamicService); requestObserver.onNext(request); requestObserver.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver2 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver2 = stub.serverReflectionInfo(responSEObserver2); handlerRegistry.removeService(dynamicService); requestObserver2.onNext(request); requestObserver2.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver3 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver3 = stub.serverReflectionInfo(responSEObserver3); requestObserver3.onNext(request); requestObserver3.onCompleted(); assertEquals( ServerReflectionResponse.MessageResponseCase.ERROR_RESPONSE,responSEObserver3.firstValue().get().getMessageResponseCase()); }
@Test public void fileContainingExtensionForMutableServices() throws Exception { ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setFileContainingExtension( ExtensionRequest.newBuilder() .setContainingType("grpc.reflection.testing.TypeWithExtensions") .setExtensionNumber(200) .build()) .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setFileDescriptorResponse( FileDescriptorResponse.newBuilder() .addFileDescriptorProto( DynamicReflectionTestDepthTwoProto.getDescriptor().toProto().toByteString()) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); handlerRegistry.addService(dynamicService); requestObserver.onNext(request); requestObserver.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver2 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver2 = stub.serverReflectionInfo(responSEObserver2); handlerRegistry.removeService(dynamicService); requestObserver2.onNext(request); requestObserver2.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver3 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver3 = stub.serverReflectionInfo(responSEObserver3); requestObserver3.onNext(request); requestObserver3.onCompleted(); assertEquals( ServerReflectionResponse.MessageResponseCase.ERROR_RESPONSE,responSEObserver3.firstValue().get().getMessageResponseCase()); }
@Test public void allExtensionNumbersOfTypeForMutableServices() throws Exception { String type = "grpc.reflection.testing.TypeWithExtensions"; ServerReflectionRequest request = ServerReflectionRequest.newBuilder() .setHost(TEST_HOST) .setAllExtensionNumbersOfType(type) .build(); ServerReflectionResponse goldenResponse = ServerReflectionResponse.newBuilder() .setValidHost(TEST_HOST) .setoriginalRequest(request) .setAllExtensionNumbersResponse( ExtensionNumberResponse.newBuilder() .setBaseTypeName(type) .addExtensionNumber(200) .build()) .build(); StreamRecorder<ServerReflectionResponse> responSEObserver = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver = stub.serverReflectionInfo(responSEObserver); handlerRegistry.addService(dynamicService); requestObserver.onNext(request); requestObserver.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver2 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver2 = stub.serverReflectionInfo(responSEObserver2); handlerRegistry.removeService(dynamicService); requestObserver2.onNext(request); requestObserver2.onCompleted(); StreamRecorder<ServerReflectionResponse> responSEObserver3 = StreamRecorder.create(); StreamObserver<ServerReflectionRequest> requestObserver3 = stub.serverReflectionInfo(responSEObserver3); requestObserver3.onNext(request); requestObserver3.onCompleted(); assertEquals( ServerReflectionResponse.MessageResponseCase.ERROR_RESPONSE,responSEObserver3.firstValue().get().getMessageResponseCase()); }
@Override public void beforeStart(final ClientCallStreamObserver<ServerReflectionRequest> requestStream) { requestStream.disableAutoInboundFlowControl(); }
Java Reflection
Java Reflection
Reflection Class
Class对象
检查一个类的信息之前,首先需要获取类的Class对象。Java中得所有类型包括基本类型(int,long,float…),即使是数组都有与之关联的Class类的对象。
如果在编译期知道一个类的名字的话,使用如下方式获取一个类的Class对象:
Class objClass = MyObject.Class;
如果在编译期不知道类的名字,但是可以在运行期获得类名的字符串:
String className = “objClass”;
Class objClass = Class.forName(className);
使用Class.forName()时,必须提供一个类的全名,即包含包名,可能会抛出ClassNotFoundException
类名
从Class对象中获取两个版本的类名
String className = objClass.getName();//包含包名
String simpleClassName = objClass.getSimpleName();//不包含包名
修饰符
可以通过Class对象来访问一个类的修饰符
int modifiers = objClass.getModifiers();
修饰符都被包装成一个int类型的数字,这样每个修饰符都是一个位标识(flag bit),这个位标识可以设置和清除修饰符的类型。使用Modifier类中的方法检查修饰符的类型:
Modifier.isAbstract(int modifiers);
Modifier.isFinal(int modifiers);
Modifier.isNative(int modifiers);
Modifier.isPrivate(int modifiers);
Modifier.isProtected(int modifiers);
Modifier.isPublic(int modifiers);
Modifier.isStatic(int modifiers);
Modifier.isStrict(int modifiers);
Modifier.isSynchronized(int modifiers);
Modifier.isVolatile(int modifiers);
包信息
Package package = objClass.getPackage();
通过Package对象可以获取包的相关信息(包名),也可以通过Manifest文件访问
父类
Class superClass = objClass.getSuperClass();
实现的接口
Class[] interfaces = objClass.getInterfaces();
此方法仅仅返回当前类实现的借口,父类的不包括。
构造器
Constructor[] constructors = objClass.getConstructors();
方法
Method[] methods = objClass.getMethods();
变量
Field[] fields = objClass.getFields();
注解
Annotation[] annotations = objClass.getAnnotations();
构造器
利用java的反射机制可以检查一个类的构造方法,并且可以在运行期间创建一个对象。
Constructor对象
通过Class对象来获取Constructor类的实例
Constructor[] constructors = objClass.getConstructors();
返回的Constructor数组包含每一个声明为public的构造方法。如果知道构造方法的参数类型:
Constructor constructor = objClass.getConstructor(new Class[]{String.class});
如果没有指定的构造方法能满足匹配的方法参数会抛出:NoSuchMethodException
构造方法参数
Class[] paraneterType = constructor.getParameterTypes();
利用Constructor对象实例化一个类
Object obj = constructor.newInstance(“constructor-arg1”);
newInstance()参数是一个可变参数列表,调用构造方法的时候必须提供精确的参数,形成一一对应。此例子中传入的是一个String类型的参数
变量
使用java反射机制可以在运行期检查一个类的变量信息(成员变量)或者获取或者设置变量的值。
获取Field对象
Field[] fields = objClass.getFields();
返回的Field对象数组包含了指定类中声明为public的所有变量集合。如果知道要访问的变量名称:
Field field = objClass.getField(“someField”);
可能会抛出NoSuchFieldException
变量名称
String fieldname = field.getName();
变量类型
Object fieldType = field.getType();
获取或设置(get/set)变量值
Class objClass = MyObject.Class;
Field field = objClass.getField(“someField”);
MyObject objectInstance = new MyObject();
Object value = field.get(objectInstance);
field.set(objectInstance, value);
set()传入的参数objectInstance应该拥有指定变量的类的实例。上述例子中传入的参数是MyObject类的实例,是因为someField是Myobject类的实例
如果变量是静态变量的话,传入null作为参数而不用传递改变量的类的实例。
方法
使用java反射可以在运行期检查一个方法的信息以及在运行期调用这个方法
获取Method对象
Method[] methods = objClass.getMethods();
返回的Method对象数组包含了指定类中声明为public的所有方法集合。
如果知道要调用方法的具体参数类型:
Method method = objClass.getMethod(“doSomething”, new Class[]{String,class});
可能会抛出NoSuchMethodException
如果获得方法没有参数,第二个参数传入null。
方法参数以及返回类型
Class[] parameterTypes = method.getParemeterTypes();
Class returnType = method.getReturnType();
通过Method对象调用方法
Method method = Myobject.class.getMethod(“donSomething”, String.class);
Object returnValue = method.invoke(null, “parameter-value”);
传入的null参数是你要调用方法的对象,如果是一个静态方法调用的话可以用null代替指定对象作为invoke()的参数,如果doSomething不是静态方法的话,需要传入有效的MyObject实例。第二个参数是一个可变参数列表,但是必须传入与调用方法的形参一一对应的实参。
getters、setters
使用反射可以在运行期检查一个方法的信息以及在运行期调用这个方法,使用这个功能同样可以获取指定类的getters和setters。
Getter
以get开头,没有方法参数,返回一个值。
Setter
以set开头,有一个方法参数,一般没有返回值。
Eg.
public static void printGettersSetters(Class aClass){
Method[] methods = aClass.getMethods();
for(Method method : methods){
if(isGetter(method)) System.out.println("getter: " + method);
if(isSetter(method)) System.out.println("setter: " + method);
}
}
public static boolean isGetter(Method method){
if(!method.getName().startsWith("get")) return false;
if(method.getParameterTypes().length != 0) return false;
if(void.class.equals(method.getReturnType()) return false;
return true;
}
public static boolean isSetter(Method method){
if(method.getParameterTypes().length != 1) return false;
return true;
}
私有变量、私有方法
通常情况下从对象的外部访问私有变量以及方法是不允许的,使用反射机制可以做到这一点。SecurityManager会现在这样使用。
访问私有变量
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
这个例子会输出”fieldValue = The Private Value”,privateString是PrivateObject实例的私有变量,调用getDeclaredField(“privateString”)方法会返回一个私有变量,调用setAccessible()方法会关闭指定类Field实例的反射访问检查,执行后不论私有还是其他的访问作用域都可以访问。
访问私有方法
PrivateObject privateObject = new PrivateObject("The Private Value");
Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
String returnValue = (String)
privateStringMethod.invoke(privateObject, null);
System.out.println("returnValue = " + returnValue);
注解
利用反射机制在运行期获取java类的注解信息。
简介
注解是插入代码中得一种注释或者说是一种元数据(meta data)。这些注解信息可以在编译期使用预编译工具进行处理(pre-compiler tools)。也可以在运行期使用java反射机制进行处理。
元注解:
@Target 表示该注解可以用于什么地方,可能的ElementType有:
CONSTRUCTOR:构造器的声明
FIFLD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类,接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存改注解信息。可选的RetentionPolicy参数
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息
@Documented 将注解包含在Javadoc中
@Inherited 允许子类继承父类中得注解
注解定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
public String name();
public String value();
}
使用:
@MyAnnotation(name="someName", value = "Hello World")
public class TheClass {
}
在interface前面的@符号表明这是一个注解。
@Target(ElementType.Type),说明这个注解改怎么使用
@Retention(RetentionPolicy.RUNTIME)表示这个注解可以运行通过反射访问。
类注解
可以在运行期访问类,方法或者变量的注解信息
Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
指定一个类的注解
Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
方法注解
下面是一个方法注解的例子:
public class TheClass {
@MyAnnotation(name="someName", value = "Hello World")
public void doSomething(){}
}
可以像这样访问方法注解:
Method method = ... //获取方法对象
Annotation[] annotations = method.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
可以像这样访问指定的方法注解:
Method method = ... // 获取方法对象
Annotation annotation = method.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
参数注解
方法参数也可以添加注解,就像下面这样:
public class TheClass {
public static void doSomethingElse(
@MyAnnotation(name="aName", value="aValue") String parameter){
}
}
你可以通过Method对象来访问方法参数注解:
Method method = ... //获取方法对象
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();
int i=0;
for(Annotation[] annotations : parameterAnnotations){
Class parameterType = parameterTypes[i++];
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("param: " + parameterType.getName());
System.out.println("name : " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
}
需要注意的是Method.getParameterAnnotations()方法返回一个注解类型的二维数组,每一个方法的参数包含一个注解数组。
变量注解
下面是一个变量注解的例子:
public class TheClass {
@MyAnnotation(name="someName", value = "Hello World")
public String myField = null;
}
可以像这样来访问变量的注解:
Field field = ... //获取方法对象</pre>
<pre>Annotation[] annotations = field.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
可以像这样访问指定的变量注解:
Field field = ...//获取方法对象</pre>
<pre>
Annotation annotation = field.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
泛型
运用泛型反射的经验法则
经典使用泛型的场景
声明一个需要被参数化(parameterizable)的类/接口
声明一个参数化类
List接口就是典型的例子
泛型方法返回类型
获得了java.lang.reflect.Method对象,那么你就可以获取到这个方法的泛型返回类型信息。如果方法是在一个被参数化类型之中那么你无法获取他的具体类型,但是如果方法返回一个泛型类(那么你就可以获得这个泛型类的具体参数化类型。你可以在“Java Reflection: Methods”中阅读到有关如何获取Method对象的相关内容。下面这个例子定义了一个类这个类中的方法返回类型是一个泛型类型:
public class MyClass {
protected List<String> stringList = ...;
public List<String> getStringList(){
return this.stringList;
}
}
可以获取getStringList()方法的泛型返回类型,换句话说,我们可以检测到getStringList()方法返回的是List而不仅仅只是一个List。如下例:
Method method = MyClass.class.getMethod("getStringList", null);
Type returnType = method.getGenericReturnType();
if(returnType instanceof ParameterizedType){
ParameterizedType type = (ParameterizedType) returnType;
Type[] typeArguments = type.getActualTypeArguments();
for(Type typeArgument : typeArguments){
Class typeArgClass = (Class) typeArgument;
System.out.println("typeArgOSC_h3_41">
可以通过反射来获取方法参数的泛型类型,下面这个例子定义了一个类,这个类中的方法的参数是一个被参数化的List: public class MyClass { protected List<String> stringList = ...; public void setStringList(List<String> list){ this.stringList = list; } } 可以像这样来获取方法的泛型参数: method = Myclass.class.getMethod("setStringList", List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for(Type genericParameterType : genericParameterTypes){ if(genericParameterType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericParameterType; Type[] parameterArgTypes = aType.getActualTypeArguments(); for(Type parameterArgType : parameterArgTypes){ Class parameterArgClass = (Class) parameterArgType; System.out.println("parameterArgOSC_h3_42">
同样可以通过反射来访问公有(Public)变量的泛型类型,无论这个变量是一个类的静态成员变量或是实例成员变量。你可以在“Java Reflection: Fields”中阅读到有关如何获取Field对象的相关内容。这是之前的一个例子,一个定义了一个名为stringList的成员变量的类。 public class MyClass { public List<String> stringList = ...; } Field field = MyClass.class.getField("stringList"); Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); for(Type fieldArgType : fieldArgTypes){ Class fieldArgClass = (Class) fieldArgType; System.out.println("fieldArgOSC_h2_43">
反射机制中是的数组,不要和java.util.Array混淆。 int[] intArray = (int[]) Array.newInstance(int.class, 3); 第一个参数表示要创建数组类型,第二个参数表示数据空间。 Array.set(intArray, 0, 123); Array.set(intArray, 1, 456); Array.set(intArray, 2, 789); System.out.println("intArray[0] = " + Array.get(intArray, 0)); System.out.println("intArray[1] = " + Array.get(intArray, 1)); System.out.println("intArray[2] = " + Array.get(intArray, 2)); 通常会用下面这个方法来获取普通对象以及原生对象的Class对象: public Class getClass(String className){ if("int" .equals(className)) return int .class; if("long".equals(className)) return long.class; ... return Class.forName(className); } 一旦你获取了类型的Class对象,你就有办法轻松的获取到它的数组的Class对象,你可以通过指定的类型创建一个空的数组,然后通过这个空的数组来获取数组的Class对象。这样做有点讨巧,不过很有效。如下例: Class theClass = getClass(theClassName); Class stringArrayClass = Array.newInstance(theClass, 0).getClass(); 这是一个特别的方式来获取指定类型的指定数组的Class对象。无需使用类名或其他方式来获取这个Class对象。 为了确保Class对象是不是代表一个数组,你可以使用Class.isArray()方法来进行校验: Class stringArrayClass = Array.newInstance(String.class, 0).getClass(); System.out.println("is array: " + stringArrayClass.isArray()); 获取了一个数组的Class对象,你就可以通过Class.getComponentType()方法获取这个数组的成员类型。成员类型就是数组存储的数据类型。例如,数组int[]的成员类型就是一个Class对象int.class。String[]的成员类型就是java.lang.String类的Class对象。 下面是一个访问数组成员类型的例子: String[] strings = new String[3]; Class stringArrayClass = strings.getClass(); Class stringArrayComponentType = stringArrayClass.getComponentType(); System.out.println(stringArrayComponentType); 下面这个例子会打印“java.lang.String”代表这个数组的成员类型是字符串。 利用反射机制在运行期动态的创建接口的实现。 可以通过使用Proxy.newProxyInstance()方法创建动态代理。newProxyInstance()方法有三个参数: 1、类加载器(ClassLoader)用来加载动态代理类。 2、一个要实现的接口的数组。 3、一个InvocationHandler把所有方法的调用都转到代理上。 如下例: InvocationHandler handler = new MyInvocationHandler(); MyInterface proxy = (MyInterface) Proxy.newProxyInstance( MyInterface.class.getClassLoader(), new Class[] { MyInterface.class }, handler); 在执行完这段代码之后,变量proxy包含一个MyInterface接口的的动态实现。所有对proxy的调用都被转向到实现了InvocationHandler接口的handler上。 调用Proxy.newProxyInstance()方法时,必须要传入一个InvocationHandler接口的实现。所有对动态代理对象的方法调用都会被转向到InvocationHandler接口的实现上,下面是InvocationHandler接口的定义: public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } 下面是它的实现类的定义: public class MyInvocationHandler implements InvocationHandler{ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //do something "dynamic" } } 传入invoke()方法中的proxy参数是实现要代理接口的动态代理对象。通常你是不需要他的。 invoke()方法中的Method对象参数代表了被动态代理的接口中要调用的方法,从这个method对象中你可以获取到这个方法名字,方法的参数,参数类型等等信息。关于这部分内容可以查阅之前有关Method的文章。 Object数组参数包含了被动态代理的方法需要的方法参数。注意:原生数据类型(如int,long等等)方法参数传入等价的包装对象(如Integer, Long等等)。 动态代理常被应用到以下几种情况中 1.数据库连接以及事物管理 2.单元测试中的动态Mock对象 3.自定义工厂与依赖注入(DI)容器之间的适配器 4.类似AOP的方法拦截器 所有Java应用中的类都是被java.lang.ClassLoader类的一系列子类加载的。因此要想动态加载类的话也必须使用java.lang.ClassLoader的子类。 一个类一旦被加载时,这个类引用的所有类也同时会被加载。类加载过程是一个递归的模式,所有相关的类都会被加载。但并不一定是一个应用里面所有类都会被加载,与这个被加载类的引用链无关的类是不会被加载的,直到有引用关系的时候它们才会被加载。 在Java中类加载是一个有序的体系。当你新创建一个标准的Java类加载器时你必须提供它的父加载器。当一个类加载器被调用来加载一个类的时候,首先会调用这个加载器的父加载器来加载。如果父加载器无法找到这个类,这时候这个加载器才会尝试去加载这个类。 类加载器加载类的顺序如下: 1、检查这个类是否已经被加载。 2、如果没有被加载,则首先调用父加载器加载。 3、如果父加载器不能加载这个类,则尝试加载这个类。 当你实现一个有重载类功能的类加载器,它的顺序与上述会有些不同。类重载不会请求的他的父加载器来进行加载。在后面的段落会进行讲解。 动态加载一个类十分简单。你要做的就是获取一个类加载器然后调用它的loadClass()方法。下面是个例子: public class MainClass { public static void main(String[] args){ ClassLoader classLoader = MainClass.class.getClassLoader(); try { Class aClass = classLoader.loadClass("com.jenkov.MyClass"); System.out.println("aClass.getName() = " + aClass.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } 动态类重载有一点复杂。Java内置的类加载器在加载一个类之前会检查它是否已经被加载。因此重载一个类是无法使用Java内置的类加载器的,如果想要重载一个类你需要手动继承ClassLoader。 在你定制ClassLoader的子类之后,你还有一些事需要做。所有被加载的类都需要被链接。这个过程是通过ClassLoader.resolve()方法来完成的。由于这是一个final方法,因此这个方法在ClassLoader的子类中是无法被重写的。resolve()方法是不会允许给定的ClassLoader实例链接一个类两次。所以每当你想要重载一个类的时候你都需要使用一个新的ClassLoader的子类。你在设计类重载功能的时候这是必要的条件。 在前面已经说过你不能使用已经加载过类的类加载器来重载一个类。因此你需要其他的ClassLoader实例来重载这个类。但是这又带来了一些新的挑战。 所有被加载到Java应用中的类都以类的全名(包名 + 类名)作为一个唯一标识来让ClassLoader实例来加载。这意味着,类MyObject被类加载器A加载,如果类加载器B又加载了MyObject类,那么两个加载器加载出来的类是不同的。看看下面的代码: MyObject object = (MyObject) myClassReloadingFactory.newInstance("com.jenkov.MyObject"); MyObject类在上面那段代码中被引用,它的变量名是object。这就导致了MyObject这个类会被这段代码所在类的类加载器所加载。 如果myClassReloadingFactory工厂对象使用不同的类加载器重载MyObject类,你不能把重载的MyObject类的实例转换(cast)到类型为MyObject的对象变量。一旦MyObject类分别被两个类加载器加载,那么它就会被认为是两个不同的类,尽管它们的类的全名是完全一样的。你如果尝试把这两个类的实例进行转换就会报ClassCastException。 你可以解决这个限制,不过你需要从以下两个方面修改你的代码: 1、标记这个变量类型为一个接口,然后只重载这个接口的实现类。 2、标记这个变量类型为一个超类,然后只重载这个超类的子类。 请看下面这两个例子: MyObjectInterface object = (MyObjectInterface) myClassReloadingFactory.newInstance("com.jenkov.MyObject"); MyObjectSuperclass object = (MyObjectSuperclass) myClassReloadingFactory.newInstance("com.jenkov.MyObject"); 只要保证变量的类型是超类或者接口,这两个方法就可以正常运行,当它们的子类或是实现类被重载的时候超类跟接口是不会被重载的。 为了保证这种方式可以运行你需要手动实现类加载器然后使得这些接口或超类可以被它的父加载器加载。当你的类加载器加载MyObject类时,超类MyObjectSuperclass或者接口MyObjectSuperclass也会被加载,因为它们是MyObject的依赖。你的类加载器必须要代理这些类的加载到同一个类加载器,这个类加载器加载这个包括接口或者超类的类。 下面这个例子是一个类加载器的子类。注意在这个类不想被重载的情况下它是如何把对一个类的加载代理到它的父加载器上的。如果一个类被它的父加载器加载,这个类以后将不能被重载。记住,一个类只能被同一个ClassLoader实例加载一次。 就像我之前说的那样,这仅仅是一个简单的例子,通过这个例子会向你展示类加载器的基本行为。这并不是一个可以让你直接用于设计你项目中类加载器的模板。你自己设计的类加载器应该不仅仅只有一个,如果你想用来重载类的话你可能会设计很多加载器。并且你也不会像下面这样将需要加载的类的路径硬编码(hardcore)到你的代码中。 public class MyClassLoader extends ClassLoader{ public MyClassLoader(ClassLoader parent) { super(parent); } public Class loadClass(String name) throws ClassNotFoundException { if(!"reflection.MyObject".equals(name)) return super.loadClass(name); try { String url = "file:C:/data/projects/tutorials/web/WEB-INF/" + "classes/reflection/MyObject.class"; URL myUrl = new URL(url); URLConnection connection = myUrl.openConnection(); InputStream input = connection.getInputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int data = input.read(); while(data != -1){ buffer.write(data); data = input.read(); } input.close(); byte[] classData = buffer.toByteArray(); return defineClass("reflection.MyObject", classData, 0, classData.length); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } 下面是使用MyClassLoader的例子: public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader(); MyClassLoader classLoader = new MyClassLoader(parentClassLoader); Class myObjectClass = classLoader.loadClass("reflection.MyObject"); AnInterface2 object1 = (AnInterface2) myObjectClass.newInstance(); MyObjectSuperClass object2 = (MyObjectSuperClass) myObjectClass.newInstance(); //create new class loader so classes can be reloaded. classLoader = new MyClassLoader(parentClassLoader); myObjectClass = classLoader.loadClass("reflection.MyObject"); object1 = (AnInterface2) myObjectClass.newInstance(); object2 = (MyObjectSuperClass) myObjectClass.newInstance(); } 下面这个就是被加载的reflection.MyObject类。注意它既继承了一个超类并且也实现了一个接口。这样做仅仅是为了通过例子演示这个特性。在你自定义的情况下你可能仅会实现一个类或者继承一两个接口。 public class MyObject extends MyObjectSuperClass implements AnInterface2{ //... body of class ... override superclass methods // or implement interface methods } 是否有任何标准方法可以访问Java Bean属性,例如 因此,我可以使用Reflection API访问此Java 今天的关于Java Reflection设置属性和java reflections的分享已经结束,谢谢您的关注,如果想了解更多关于com.badlogic.gdx.utils.reflect.ReflectionException的实例源码、io.grpc.reflection.v1alpha.ServerReflectionRequest的实例源码、Java Reflection、Java Reflection Beans属性API的相关知识,请在本站进行查询。 本文标签:泛型方法参数类型
泛型变量类型
数组
java.lang.reflect.Array
创建一个数组
访问一个数组
获取数组的Class对象
获取数组的成员类型
动态代理
创建代理
InvocationHandler接口
常见用例
动态类加载、重载
类加载器
类加载体系
类加载
动态类加载
动态类重载
自定义类重载
类加载/重载实例
Java Reflection Beans属性API
class A {
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
bean属性名称,以便在更改属性的值时,在设置和获取该属性的值时自动调用getName和setName的方法。