第一次发帖,标题很垃圾。 我正在尝试使用类型推断,但在使用工厂模式时很难让它正常工作,让我写一些代码来让它更清楚一点:
private class ParentObject { }
private class ChildObject extends ParentObject { }
private interface Template<T extends ParentObject> {
void doSomething(T object);
}
private class TemplateImpl implements Template<ChildObject> {
public void doSomething(ChildObject object) { }
}
所以我有一些继承自 Template 的类,这些类对继承自 ParentObject 的对象执行某些操作(我在本文中只发布了其中一个)。 现在我遇到的这个问题是,当我尝试生成这些模板类之一时,我在尝试执行此操作时不断收到“不兼容类型”错误:
private class Factory {
public <T extends ParentObject> Template<T> generate() {
return new TemplateImpl(); // here is the error
}
}
private class Service {
public <T extends ParentObject> void magic() {
Factory f = new Factory();
Template<T> a = f.generate();
}
}
或者当我这样做时,我收到“未检查的分配”警告(代码按预期工作,但如果我做错了什么,我宁愿修复它!):
private class AlternativeFactory {
public Template generate() {
return new TemplateImpl();
}
}
private class Service {
public <T extends ParentObject> void magic() {
AlternativeFactory af = new AlternativeFactory();
Template<T> b = af.generate(); // warning here
}
}
有没有人知道我如何在没有任何警告的情况下完成这项工作?如果这是一个简单的类型推理,我还没有使用太多,所以很抱歉! 我不明白的是为什么我不能将 TemplateImpl 作为模板返回,因为它实现了模板?
谢谢!
编辑:事实上,我想要实现的工厂看起来像这样,而且似乎这就是类型推断存在的问题:
private class Factory {
public Template<T extends ParentObject> generate(int option) {
switch (option) {
case 1:
return new TemplateA(); // implements Template<A> where A extends ParentObject
case 2:
return new TemplateB(); // implements Template<B> where B extends ParentObject
default:
throw new IllegalArgumentException();
}
}
}
编辑:决定使用我上面提供的代码 (AlternativeFactory),并在调用工厂的服务方法中使用 SuppressWarnings,因为看起来我希望实现的目标是不可能的。我知道这使用原始类型并且是不好的做法,但我对这些 Template 对象和 AlternativeFactory 进行了很多测试,包括类型检查,所以现在必须这样做。
最佳答案
TemplateImpl仅与 Template<ChildObject> 兼容, 所以 new TemplateImpl()不能是 public <T extends ParentObject> Template<T> generate() 的有效返回值- 因为 T可以是 ParentObject 的不同子类
最简单的更改是制作 Template一个类:
private class Template<T extends ParentObject> {
void doSomething(T object){/*implement*/}
}
或者,如果它必须是一个接口(interface),则生成 TemplateImpl也通用:
private class TemplateImpl<T extends ParentObject> implements Template<T> {
public void doSomething(ChildObject object) { }
}
这将允许您的工厂使用类型参数:
private class Factory {
public <T extends ParentObject> Template<T> generate() {
return new TemplateImpl<T>(); //T is not bound to ChildObject
}
}
如果您只需要确保TemplateImpl仅适用于 Template<ChildObject> ,那么你的工厂方法不需要是通用的:
private class TemplateImpl implements Template<ChildObject> {
public void doSomething(ChildObject object) { }
}
//and the factory:
private class Factory {
public Template<ChildObject> generate() {
return new TemplateImpl(); //TemplateImpl is a Template<ChildObject>
}
}
应避免使用第二种解决方案,因为它使用原始类型。
关于Java:返回一个实现具有类型推断的接口(interface)的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56483486/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/