Java 在包含成员的ClientBundle中包含一个成员ClientBundle是一种正常的做法吗?
在我的应用程序中,我有Java 在包含成员的ClientBundle中包含一个成员ClientBundle是一种正常的做法吗?,java,gwt,clientbundle,Java,Gwt,Clientbundle,在我的应用程序中,我有MyAppResources,其中主要包含应用程序的自定义样式。我在想,将自定义样式应用于标准小部件(如CellTable)以及布局和自定义小部件上的自定义样式的好方法是什么 我的问题: 由于MyAppResources是一个单例(如其他帖子所述,它不必是单例),但CellTableResources不是,而且CellTableResources是该实例的一个成员,该实例也是扩展ClientBundle的接口,是否会在每个MyAppResources.INSTANCE.Ce
MyAppResources
,其中主要包含应用程序的自定义样式。我在想,将自定义样式应用于标准小部件(如CellTable)以及布局和自定义小部件上的自定义样式的好方法是什么
我的问题:
由于MyAppResources是一个单例(如其他帖子所述,它不必是单例),但CellTableResources
不是,而且CellTableResources
是该实例的一个成员,该实例也是扩展ClientBundle
的接口,是否会在每个MyAppResources.INSTANCE.CellTableResources().foo()上创建代理“CellTableResources”
如果是这样,我可以创建一个MyAppResources.CELLTABLE\u RESOURCE\u实例来解决这个问题吗?或者,即使有大量调用MyAppResources.INSTANCE.cellTableResources()。#
,代理的创建是否可以忽略不计
第二,更多的是讨论问题:在这种情况下,使用多个ClientBundle
s的最佳实践是什么?我是否应该使用GWT.create(CellTableResources.class)单独使用CellTableResources
(从MyAppResources
中删除它)
在需要它的小部件中(或者像我为MyAppResources
使用的单例程序)
MyAppResources
:
public interface MyAppResources extends ClientBundle {
public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class);
@Source("MyAppStyles.css")
public MyAppCssResource css();
public CellTableResources cellTableResources();
}
public interface CellTableResources extends CellTable.Resources {
interface CellTableStyle extends CellTable.Style {
}
@Override
@Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
CellTableStyle cellTableStyle();
@Source("green_light.png")
ImageResource getGreenLight();
//...
}
CellTableResources
:
public interface MyAppResources extends ClientBundle {
public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class);
@Source("MyAppStyles.css")
public MyAppCssResource css();
public CellTableResources cellTableResources();
}
public interface CellTableResources extends CellTable.Resources {
interface CellTableStyle extends CellTable.Style {
}
@Override
@Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
CellTableStyle cellTableStyle();
@Source("green_light.png")
ImageResource getGreenLight();
//...
}
感谢阅读。多部分问题,因此我将尝试分几个部分来回答这个问题:
GWT.create()的成本是多少?
GWT类的大部分内容都是“魔法”,你不能用其他方式为自己编写,因为它们要求编译器为你填写特定的细节。在dev模式下运行与编译为JS时,它们通常是不同的
在GWT.create
的情况下,它被编译成new
——它只用于创建新实例。那么,一个新实例相对于一个单实例的成本是多少呢?这完全取决于正在创建的对象。如果对象中没有字段,那么成本基本上是免费的-事实上,编译器可能会选择实际删除构造函数调用,并将所有后续方法重写为static
大多数情况下都会发生这种情况-GWT.create
应该被认为是非常便宜的,除非您正在做一些愚蠢的事情,比如在运行多次的循环中调用它
当我在另一个ClientBundle
中列出一个ClientBundle
方法时会发生什么?
那么,当您在ClientBundle
中列出任何内容时会发生什么
可以在ClientBundle中列出的任何内容都必须用@ResourceGeneratorType
注释,指明如何生成该类型。例如,下面是ImageResource
:
/**
* Provides access to image resources at runtime.
*/
@DefaultExtensions(value = {".png", ".jpg", ".gif", ".bmp"})
@ResourceGeneratorType(ImageResourceGenerator.class)
public interface ImageResource extends ResourcePrototype {
//...
它调用ImageResourceGenerator
根据需要创建图像。该注释中描述的任何类都必须实现com.google.gwt.resources.ext.ResourceGenerator
,它描述了如何准备工作、如何创建必要的字段、如何初始化字段以及如何完成
那么对于ClientBundle本身来说这是什么样子呢?查看com.google.gwt.resources.rg.BundleResourceGenerator
——它是一个非常简单的类,只需对给定的方法类型调用gwt.create()
。因此,可以预见,这意味着这些“子”ClientBundle是通过GWT.create创建的,与您在其他情况下所做的大致相同
好吧,在这个特殊情况下这意味着什么?
事实证明,ClientBundles实例没有跟踪新创建对象的字段,而是有静态成员,它们使用这些静态成员来代替有效的单例。这意味着,一旦您调用了一次方法,它返回的实例将与您下次调用它时创建的实例相同。具有相同内容的两个不同的ClientBundle当然会保留对象的两个不同副本,但创建ClientBundle多少次并不重要,它的内部始终是相同的
还有别的吗?
是的!请记住,您在这里处理的是接口,而不是类,因此您实际上可以一次扩展多次
public interface MyAppResources extends
ClientBundle,
CellTable.Resources,
CellTree.Resources {//etc
//...
现在,如果两个接口描述相同的方法,您可能会遇到问题,但如果不是,则在生成sprited图像时,这会提供一个优势。每个ClientBundle
在准备使用时都会使用自己的图像池-如果ClientBundle
中有ClientBundle
,它们不会一起将图像分割成更大的片段。要实现这一点,只需输入一个ClientBundle
type。这在您的特定情况下可能并不重要,但我认为这也值得一提。您的标题会询问这种做法是否可行,但正文中的问题会询问是否在每次方法调用时创建了新实例。如果创建了一个或多个实例并不重要(您指出了这一点),那么您为什么要问?我不确定是否实际上创建了CellTableResources
的一个或多个实例并不重要,因此我问是否应该保留它。我可以假设即使CellTableResources
是一个接口,它也会为singletonMyAppResources
实例化一次吗?我明白你的意思,如果通过使用GWT.create(…)
,包含ClientBundle
的客户端实际上几乎是一个单例,那对会员来说也没关系。但是,我没有为成员使用GWT.create(…)
。还有,有几个这样的成员会有什么累积效应呢?好的,我明白了-我会尝试在一个真实的答案中总结利弊…一个彻底的答案;非常感谢。我真想知道