- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个名为以下名称的类com.test.TestClass
在我的代码中的某一时刻,我必须仅通过类名字符串来获取此类的实例。我尝试过使用 GWT.create()但它仅在开发模式下工作。谁能告诉我如何从类名获取 gwt 中的实例。
最佳答案
由于反射在客户端是不可能的,因此模仿反射的唯一解决方案是使用延迟绑定(bind)。
使用延迟绑定(bind)来发现您希望在编译期间使用类名实例化的所有类。您可以在所有此类上使用标记接口(interface)来帮助 TypeOracle 识别它们。您动态生成一个工厂类,它接受类的简单名称并返回该类的新实例化的对象。该方法非常简单,您会在谷歌的引导教程中找到延迟绑定(bind)的很好的解释。
编辑:-一些帮助您入门的框架代码。 (我的生产代码的精简版本,检查生成文件中的编译器错误!并调试流程)
First> 将以下简介添加到 *.gwt.xml 中,以便编译器调用我们的 com.package.ReflectionGenerator,它将生成一个简单的工厂类来模拟客户端上的反射侧面。
<generate-with class="com.package.ReflectionGenerator">
<when-type-assignable class="com.package.client.Reflection" />
</generate-with>
下一步>为我们的工厂类定义一个接口(interface)
public interface Reflection {
public <T, V extends T> T instantiate( Class<V> clazz );
}
最后>实现 ReflectionGenerator
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
public class ReflectionGenerator extends Generator
{
@Override
public String generate( TreeLogger logger, GeneratorContext context, String typeName ) throws UnableToCompleteException
{
TypeOracle oracle = context.getTypeOracle( );
JClassType instantiableType = oracle.findType( MarkerInterface.class.getName( ) );
List<JClassType> clazzes = new ArrayList<JClassType>( );
PropertyOracle propertyOracle = context.getPropertyOracle( );
for ( JClassType classType : oracle.getTypes( ) )
{
if ( !classType.equals( instantiableType ) && classType.isAssignableTo( instantiableType ) )
clazzes.add( classType );
}
final String genPackageName = "com.package.client";
final String genClassName = "ReflectionImpl";
ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory( genPackageName, genClassName );
composer.addImplementedInterface( Reflection.class.getCanonicalName( ) );
composer.addImport( "com.package.client.*" );
PrintWriter printWriter = context.tryCreate( logger, genPackageName, genClassName );
if ( printWriter != null )
{
SourceWriter sourceWriter = composer.createSourceWriter( context, printWriter );
sourceWriter.println( "ReflectionImpl( ) {" );
sourceWriter.println( "}" );
printFactoryMethod( clazzes, sourceWriter );
sourceWriter.commit( logger );
}
return composer.getCreatedClassName( );
}
private void printFactoryMethod( List<JClassType> clazzes, SourceWriter sourceWriter )
{
sourceWriter.println( );
sourceWriter.println( "public <T, V extends T> T instantiate( Class<V> clazz ) {" );
for ( JClassType classType : clazzes )
{
if ( classType.isAbstract( ) )
continue;
sourceWriter.println( );
sourceWriter.indent( );
sourceWriter.println( "if (clazz.getName().endsWith(\"." + classType.getName( ) + "\")) {" );
sourceWriter.indent( );
sourceWriter.println( "return (T) new " + classType.getQualifiedSourceName( ) + "( );" );
sourceWriter.outdent( );
sourceWriter.println( "}" );
sourceWriter.outdent( );
sourceWriter.println( );
}
sourceWriter.indent();
sourceWriter.println("return (T) null;");
sourceWriter.outdent();
sourceWriter.println();
sourceWriter.println("}");
sourceWriter.outdent( );
sourceWriter.println( );
}
}
这应该在您的工作区中生成工厂类 ReflectionGenerator,检查生成的文件并调整源编写器代码以生成您想要的代码。
用法 GWT.create( Reflection.class ).instantiate( YourClass.class );
我在生成器中使用了标记接口(interface)'MarkerInterface'
来限制工厂支持的类的数量,因此所有参与的类都必须实现'MarkerInterface'
关于gwt - 如何从gwt中的类名创建新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3034881/
我是一名优秀的程序员,十分优秀!