- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是什么意思大家好 - 我正在看一个名为“鱼与熊掌兼得:Java 元编程”的演示文稿
演讲者是 Howard M. Lewis Ship,他是 Tapestry 的作者之一 - 在制作该作品的过程中,创建了一个名为“Plastic ”的子项目来利用 ASM 来改变字节码。
我不会假装自己是专家,但最终结果应该是我可以编写代码,以便可以使用带注释的类、方法和字段来生成进一步的 java 代码,从而减少样板代码。
我的问题下面的代码是演示我的问题的完整示例。测试示例应修改 EqualsDemo 类,使其包含 equals() 和 hashCode() 的实现。运行它时,我收到一个错误,基本上表明我无法将“com.example. Plastic.transformed.EqualsDemo”类型的对象强制转换为“com.example. Plastic.transformed.EqualsDemo”(是的,同一个类) .
演示者刚刚提到这些错误很烦人,但没有提及它们的来源 - 到目前为止我的搜索表明它们与不同的类加载器有关。然而,我完全无法解决这个问题,因此我的问题在这里(!)
com.example.plastic.transformed.EqualsDemo cannot be cast to com.example.plastic.transformed.EqualsDemo
at MainClass.main(MainClass.java:28)
那么我需要做什么?替换类加载器? (如果是这样,怎么办?)或者是否有塑料的某些部分我不明白?为了使事情顺利进行,我需要使用一些用于生成代理对象或类似对象的方法?
PS!到目前为止,我发现的示例在带注释的实例的最终使用中都使用了我认为的 Groovy。希望有人比我更有能力:)
链接:Tapestry 主页(塑料作为 jar 包含在下载中):http://tapestry.apache.org/
import java.util.ArrayList;
import java.util.List;
import org.apache.tapestry5.internal.plastic.StandardDelegate;
import org.apache.tapestry5.plastic.ClassInstantiator;
import org.apache.tapestry5.plastic.PlasticManager;
import com.example.plastic.transformer.EqualsHashCodeTransformer;
import com.example.plastic.transformed.EqualsDemo;
public class MainClass {
public static void main(String[] args) {
List<String> pList = new ArrayList<String>();
pList.add("com.example.plastic.transformed");
PlasticManager pm = PlasticManager
.withContextClassLoader()
.delegate( new StandardDelegate(new EqualsHashCodeTransformer()) )
.packages(pList)
.create();
final String EQUALSDEMO = "com.example.plastic.transformed.EqualsDemo";
ClassInstantiator<EqualsDemo> i = pm.getClassInstantiator(EQUALSDEMO);
i.newInstance().hashCode();
/*
com.example.plastic.transformed.EqualsDemo cannot be cast to com.example.plastic.transformed.EqualsDemo
at MainClass.main(MainClass.java:28)
*/
}
}
package com.example.plastic.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ImplementEqualsHashCode {
}
package com.example.plastic.transformer;
import java.util.ArrayList;
import java.util.List;
import org.apache.tapestry5.plastic.FieldHandle;
import org.apache.tapestry5.plastic.MethodAdvice;
import org.apache.tapestry5.plastic.MethodDescription;
import org.apache.tapestry5.plastic.MethodInvocation;
import org.apache.tapestry5.plastic.PlasticClass;
import org.apache.tapestry5.plastic.PlasticClassTransformer;
import org.apache.tapestry5.plastic.PlasticField;
import com.example.plastic.annotations.*;
public class EqualsHashCodeTransformer implements PlasticClassTransformer {
private MethodDescription EQUALS = new MethodDescription("boolean", "equals", "java.lang.Object");
private MethodDescription HASHCODE = new MethodDescription("int", "hashCode");
private static final int PRIME = 37;
public void transform(PlasticClass plasticClass){
//check that the class is annotated
if(!plasticClass.hasAnnotation(ImplementEqualsHashCode.class)) {
return;
}
List<PlasticField> fields = plasticClass.getAllFields();
final List<FieldHandle> handles = new ArrayList<FieldHandle>();
for(PlasticField field : fields){
handles.add(field.getHandle());
}
//HashCode method introduction :)
plasticClass.introduceMethod(HASHCODE).addAdvice(new MethodAdvice() {
public void advise(MethodInvocation invocation){
Object instance = invocation.getInstance();
int result = 1;
for(FieldHandle handle : handles){
Object fieldValue = handle.get(instance);
if(fieldValue != null)
result = (result * PRIME) + fieldValue.hashCode();
}
invocation.setReturnValue(result);
//Don't proceed to the empty introduced method
}
});
plasticClass.introduceMethod(EQUALS).addAdvice(new MethodAdvice() {
public void advise(MethodInvocation invocation) {
Object thisInstance = invocation.getInstance();
Object otherInstance = invocation.getParameter(0);
invocation.setReturnValue(isEqual(thisInstance, otherInstance));
//Don't proceed to the empty introduced method
}
private boolean isEqual(Object thisInstance, Object otherInstance) {
if(thisInstance == otherInstance)
return true;
if(otherInstance == null)
return false;
if(!(thisInstance.getClass() == otherInstance.getClass()))
return false;
for(FieldHandle handle : handles){
Object thisValue = handle.get(thisInstance);
Object otherValue = handle.get(otherInstance);
if(!(thisValue == otherValue || thisValue.equals(otherValue)))
return false;
}
return true;
}
});
}
}
package com.example.plastic.transformed;
import com.example.plastic.annotations.ImplementEqualsHashCode;
@ImplementEqualsHashCode
public class EqualsDemo {
private int intValue;
private String stringValue;
public int getIntValue(){
return intValue;
}
public void setIntValue(int intValue){
this.intValue = intValue;
}
public String getStringValue(){
return stringValue;
}
public void setStringValue(String stringValue){
this.stringValue = stringValue;
}
}
最佳答案
您不想将包添加到 Plastic 管理器中 - 它使用不同的类加载器并加载这些类,在这些包中制作类的两份副本(一份在父类加载器中,一份在 Plastic 类加载器中) )这会给你当框架尝试转换为你的类时看到的 ClassCastException 。试试这个:
import org.apache.tapestry5.internal.plastic.StandardDelegate;
import org.apache.tapestry5.plastic.ClassInstantiator;
import org.apache.tapestry5.plastic.PlasticManager;
public class MainClass {
public static void main(String[] args) {
PlasticManager pm = PlasticManager
.withContextClassLoader()
.delegate(new StandardDelegate())
.create();
ClassInstantiator<EqualsDemo> ci = pm.createClass(EqualsDemo.class, new EqualsHashCodeTransformer());
System.out.println(ci.newInstance().hashCode());
}
}
关于java - 使用 Plastic 框架进行代码生成时出现棘手的 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10921361/
我看到他们有一个看起来像 WPF 的 Windows 版本,一个 mac 屏幕截图在标题栏中显示 Mono。 它是用 Mono 用 C# .NET 编写的吗? (我只是问,因为他们似乎做对了) 谢谢。
我将lart 5.2与https://github.com/sleimanx2/plastic一起使用,并且有一个名为job_ads的表。 job_ads表具有一个类型列,该列有时为null。我想搜索
我已经对它进行了一段时间的评估,测试了不同的场景并尝试了不同的配置。在此期间,我多次删除并重新创建我的存储库。每次,我都必须返回并重新分配每个存储库的所有权限。 目前,我已决定为公共(public)代
这是什么意思大家好 - 我正在看一个名为“鱼与熊掌兼得:Java 元编程”的演示文稿 演讲者是 Howard M. Lewis Ship,他是 Tapestry 的作者之一 - 在制作该作品的过程中,
如何备份 Plastic SCM 中的存储库? 手动备份数据库就足够了吗? 如果系统服务器崩溃,我将来可以恢复并开始使用存储库吗? 或者有没有其他方法或接口(interface)来完成这项工作? 最佳
我如何知道 Plastic SCM 存储库占用了多少磁盘空间? 最佳答案 这取决于您拥有的后端configured (SQL Server、MySQL、Firebird 等...)。 一旦您了解了正在
过去几个晚上我一直在研究版本控制应用程序,主要是在这里阅读帖子和访问网站。我正在为我自己的个人爱好 C# 项目寻找 SCM。 我希望版本控制服务器位于我的 PC 本地,无意进行远程或内联网或多用户开发
我正在评估 SCM 是否有可能脱离 SourceSafe。塑料 SCM 给人留下了良好的印象。我看到它有一个来自 SourceSafe 的导入器,但找不到很多关于它如何处理一些 VSS 特性的信息——
我目前正在“玩”Plastic以及他们的(全新的)TeamCity 集成插件。 插件简介说“在 Windows 系统上安装 Team City 时,它通常使用 SYSTEM 用户帐户。我们建议更改执行
我已经设置了一个新的 JIRA 服务器与 plasticscm 一起使用。 5.4.16.712 中的 Windows 客户端在首选项中有一个很好的选项卡,用于选择和设置问题跟踪工具。虽然 linux
我知道 git 托管服务之间可能会发生同步,但我想知道是否可以在本地使用 git,然后将其设置为可以与 Plastic SCM 服务器同步的方式。 即与 gitsync 的作用相反...我的中央共享是
是否有一个简单的工作流程可以在内部使用 Plastic SCM,同时最好使用 github 或 Bitbucket 等流行的代码托管服务之一,而不需要“双重簿记”? 最佳答案 正如 VonC 指出的那
我需要一些有关使用可写 Xlink 的信息。 我有两个项目,我们称它们为项目A 和 B项目 . 每个项目都有自己的存储库: repo A ;和 repo B .每个项目也有自己的工作区: C:\项目\
我是一名优秀的程序员,十分优秀!