我有以下类(class)
public abstract interface X
{
public abstract void f() throws java.io.IOException;
}
public class Y implements X
{
public void f() throws java.io.IOException
{
throw new java.ioIOException("Hello");
}
public static void main(String [] args)
{
X x = new Y();
try
{
x.f();
}
catch (IOException e)
{
System.out.println("Caught");
}
}
}
现在我编译两者并得到 X.class 和 Y.class。
现在我更改 X 以删除 throws
public abstract interface X
{
public abstract void f();
}
显然,如果我重新编译 X 和 Y,Y 的编译将失败
Y.java:4: f() in Y cannot implement f() in X; overridden method does not throw j
ava.io.IOException
但是,我只需要重新编译 X.java 并保留使用较旧的 X.java 编译的 Y.class。
在这种情况下会发生什么 - 它是否定义明确?
或者它是否属于未定义的类别 - 即任何事情都可能发生?
是否有任何保证 - 即,如果我始终在 Windows 下的 Java 1.6.32 下运行它,我可以相信没有坏事发生吗?
更新:更新它是因为一些答案说我会在运行时得到一个IncompatibleClassChangeError。但我没有。
步骤
1) 如上所述编译 X.java 和 Y.java。运行 Y。
输出:捕获
2) 更改 X.java 以注释掉抛出。重新编译 X.java。 不要重新编译 Y.java。
运行 Y
输出:捕获
我在 Windows 7 上运行 java
编译器
javac 1.6.0_35
运行时
java version "1.6.0_35"
Java(TM) SE Runtime Environment (build 1.6.0_35-b10)
Java HotSpot(TM) Client VM (build 20.10-b01, mixed mode, sharing)
最佳答案
这是目前 Java 中的一个限制。创建一个扩展您当前接口(interface)的子接口(interface),如果您确实需要它,则无一异常(exception)地覆盖该方法。一般来说,这称为“二进制更改”,会在代码运行时导致链接断开,并且在 JLS 中定义明确(有一整章,JLS 13,您特别需要 JLS 13.5)。
编辑:经过进一步调查,事实证明我错了。来自 JLS 13.4.21 :
Changes to the
throwsclause of methods or constructors do not break compatibility with pre-existing binaries; these clauses are checked only at compile time.
但是,我仍然建议不要这样做,因为这意味着已检查的异常在运行时基本上可以变成未检查的。
关于java - 在不重新编译实现类的情况下更改接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14734345/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案