我想知道为什么这是一个有效的覆盖:
public abstract class A {
public abstract <X> Supplier<X> getSupplier();
public static class B extends A {
@Override
public Supplier<String> getSupplier() {
return String::new;
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这不是:
public abstract class A {
public abstract <X> Supplier<X> getSuppliers(Collection<String> strings);
public static class B extends A {
@Override
public Supplier<String> getSuppliers(Collection<String> strings) {
return String::new;
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据JLS§8.4.8.1,B.getSupplier必须是一个副主题A.getSupplier:
在类C中声明或继承的实例方法mC,覆盖C类中声明的另一个方法mA,iff以下所有条件都为真:
- ...
- mC的签名是mA签名的子签名(§8.4.2).
- ...
Subsignatures定义在JLS§8.4.2:
两种方法或构造,M和N,具有相同的签名,如果它们具有相同的名称,相同类型的参数(如果有的话)(§8.4.4),并且,调整所述形参类型的N到所述类型参数后M,相同的形式参数类型.
方法m1的签名是方法m2的签名的子签名,如果:
因此它似乎B.getSupplier …
在基于Spring的应用程序中,我有一个执行某些计算的服务Index.Index计算(比如1s)相对昂贵,但检查现状(比如20ms)相对便宜.实际代码无关紧要,它遵循以下几行:
public Index getIndex() {
return calculateIndex();
}
public Index calculateIndex() {
// 1 second or more
}
public boolean isIndexActual(Index index) {
// 20ms or less
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Spring Cache通过@Cacheable注释缓存计算的索引:
@Cacheable(cacheNames = CacheConfiguration.INDEX_CACHE_NAME)
public Index getIndex() {
return calculateIndex();
}
Run Code Online (Sandbox Code Playgroud)
我们目前配置GuavaCache为缓存实现:
@Bean
public Cache indexCache() {
return new GuavaCache(INDEX_CACHE_NAME, CacheBuilder.newBuilder()
.expireAfterWrite(indexCacheExpireAfterWriteSeconds, TimeUnit.SECONDS)
.build());
}
@Bean
public CacheManager indexCacheManager(List<Cache> caches) {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caches);
return cacheManager;
}
Run Code Online (Sandbox Code Playgroud)
我还需要检查缓存的值是否仍然是实际值并刷新它(理想情况下是异步的)如果不是.理想情况下应该如下:
getIndex() …我试图使用相同的生成类,但在单独的包中.所以结构看起来应该是这样的:
com.test.common
-commonType.java
com.test.A
-objectA.java
com.test.B
-objectB.java
Run Code Online (Sandbox Code Playgroud)
但我一直这样:
com.test.common
-commonType.java
com.test.A
-objectA.java
-commonType.java
com.test.B
-objectB.java
-commonType.java
Run Code Online (Sandbox Code Playgroud)
我的common.xsd看起来像这样:
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/common"
xmlns="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="CommonType">
<xs:sequence>
<xs:element name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
objectA.xsd看起来像
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/objectA"
xmlns:common="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="ObjectA">
<xs:sequence>
<xs:element name="size" type="xs:string" />
<xs:element name="commonA" type="common:CommonType" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
而objectB.xsd看起来像:
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/objectB"
xmlns:common="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="ObjectB">
<xs:sequence>
<xs:element name="version" type="xs:string" /> …Run Code Online (Sandbox Code Playgroud) 我有以下API兼容性问题,并寻找解决方法.
TL; DR有没有办法在Java中为类创建"别名"?即com.acme.foo.SomeEnum成为别名的一些技巧com.acme.bar.SomeEnum?
很长的故事.(我为了避免指点而对它进行了一些调整.)
我正在使用一个强大的Java工具,它也支持插件.没有严格定义的公共 API(从某种意义上说,你能够和不能触摸),只是通常的私有/受保护/包/公共类,方法和字段.有定义的扩展点(比如,扩展com.acme.plugin.Plugin类),但是你可以访问工具内部的广泛区域.
在最近的次要版本更新(例如,1.2.3- > 1.2.4)中,工具开发人员已将一个枚举类移动到另一个包 - com.acme.foo.SomeEnum成为com.acme.bar.SomeEnum.我认为它被认为是一个微不足道的重构,而不是一个严重的重组.
然而,这个类似乎已被许多插件使用.结果是这些插件现在与最新版本不兼容.大多数插件非常有用,但没有主动维护.人们在几年前写了他们 - 他们刚刚工作了多年,有几十个版本更新.因此,这可能会对工具的插件生态系统产生负面影响.
我的问题是,如果有一些Java中的方法来创建一个"别名" com.acme.foo.SomeEnum的com.acme.bar.SomeEnum?这将允许旧插件继续使用新版本的工具.
一些类加载器技巧?在JavaScript中,对于垫片来说是微不足道的,但是在Java中?
我为什么这么问.我是Maven插件的作者,它包含了有问题的工具.因此,我可以轻松地将糖添加到这种咖啡中,就像类加载器一样.如果有技术方法可以完成这项工作,那么我将能够保存大部分工具的插件生态系统 - 至少对于Maven用户而言.
我已经联系过该工具的供应商,但不确定是否成功.
只是要清楚- 我是不是有问题的工具的供应商.我(a)为The Tools编写插件(并且更新我的插件没有大麻烦)和(b)是the-tool-maven-plugin允许在Maven构建中执行The Tool 的作者.我还对The Tool进行了很多咨询并关注它的生态系统(有很多非常有用的插件).
更新
故事结束:The Tool的开发人员将我的观点考虑在内,并决定恢复变更.为此感到荣幸!
我是其中一个Maven插件的作者(不是Apache/Codehaus,完全独立).有时我得到支持请求或测试用例,我真的需要用现有的调试插件的执行pom.xml.基本上我得到的测试用例是样本/测试项目(pom.xml有src/main/resoures,src/main/java等等).
我需要的是一种方法:
pom.xml.MyMojo- 完全初始化/配置,并注入所有组件和参数.MyMojo.通过调试我的意思是能够设置和停止断点(也是有条件的),在源代码上进/出/结束.
理想情况下,我希望能够executeMyMojoFrom(new File("pom.xml"))- 例如在JUnit测试或main某个类的方法中.(我可以提供groupId,artifactId等等.所有其他的定义应该只从装pom.xml).
我怎样才能做到这一点?
到目前为止我尝试过的:
Debug As...在pom.xmlEclipse中-不工作不够好(源代码没有找到,断点不作为它不是一个Java项目环境中工作)mvnDebug由帕斯卡尔Thivent建议,然后远程调试在Eclipse 这里.这是迄今为止最好的选择.但是,远程调试意味着mvnDebug单独启动,并且也不能保证Eclipse中的JAR与mvnDebug使用的JAR完全相同.所以这里有一定的距离.maven-plugin-testing-harness - 我实际上认为这将完成任务.但首先我只是跳了几个小时,才开始.所有重要的依赖项都是"提供"的,所以我首先要弄清楚这些工件的正确组合.然后 - 发现AbstractMojoTestCase 只能在你要测试的插件模块中工作.当我认为这maven-plugin-testing-harness是Maven插件的测试工具时,我可能错了.它似乎是该插件模块中插件的测试工具.这不是不合逻辑的,但对我的情况没有帮助.我想在其他模块中测试我的插件.所以现在我用远程调试解决方案获得了最好的结果.但我正在寻找的东西真的像maven-plugin-testing-harness插件模块那样硬连线.有没有人碰巧有提示,如果这样的方法存在于Maven工件的某个地方?
更具体地说,我想写一些类似的东西:
public void testSomething()
throws Exception
{
File pom …Run Code Online (Sandbox Code Playgroud) 是否可以在加载页面后通过JavaScript更改浏览器历史记录中页面的标题?应该是跨浏览器(当然)并且在不支持HTML5 History API的浏览器上工作,我的主要目标浏览器是Chrome.
我已经尝试了很多方法,但它们似乎都不可靠.这是我上次尝试过的(history.js):
<html>
<head>
<title>Standard title</title>
<script src="https://rawgit.com/browserstate/history.js/master/scripts/bundled-uncompressed/html4%2Bhtml5/native.history.js"></script>
</head>
<body>
<script>
window.setTimeout(function(){
document.title = "My custom title";
History.replaceState({}, "My custom title", window.location.href);
}, 3000);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果我在页面加载Standard title后3秒内在Chrom中加载历史页面,我看到,在3秒后我得到了My custom title.
为什么我需要这个:我有一个只适用于JavaScript的应用程序(Angular 1),它运行在不同的环境(开发,测试,生产)上.我想显示一个标题MyApp (<environmentName>),但我不想为每个环境构建我的应用程序的单独版本.相反,应用程序可以通过AJAX从后端请求环境信息并更新页面标题.所有这一切都很好(页面标题得到更新),但浏览器历史记录仍显示"标准"标题.
有没有办法在浏览器历史记录中更改页面的标题?
我正在为我的公司准备评估JavaScript模块化方法.我们正在为我们的项目定义"JavaScript最佳实践",模块化是一个核心问题.
从我迄今为止的研究中发现了两种主要方法:
周围有大量的加载器,插件,库等.
除此之外,还有goog.provide/ goog.require来自Google Closure Library.
还有其他方法需要考虑吗?我错过了哪些重要/相关的规格?
我们的要求简要说明:
潜在:
答案的新建议:
附注:
我是某个开源库的作者.其中一个公共接口具有使用原始类型的方法Collection,例如:
public StringBuilder append(..., Collection value);
Run Code Online (Sandbox Code Playgroud)
我收到Collection is a raw type. References to generic type Collection<E> should be parameterized警告.
我正在考虑修复这些警告.实现实际上并不关心集合中元素的类型.所以我在考虑更换Collection<?>.
但是,这些方法是我的库的公共接口的一部分.客户端代码可以调用这些方法或提供这些公共接口的自己实现,从而实现这些方法.我担心更改Collection为Collection<?>会破坏客户端代码.所以这是我的问题.
如果我在公共接口中更改Collection- > Collection<?>,可能会导致:
我们有一个微服务,它从队列中获取一些JSON数据,稍微处理它并再次通过队列发送处理结果.在微服务中,我们不JSONObject直接使用喜欢的东西,我们使用Jackson将JSON映射到Java类.
处理时,微服务只对传入消息的某些属性感兴趣,而不是所有属性.想象一下它刚收到
{
"operand1": 3,
"operand2": 5,
/* other properties may come here */
}
Run Code Online (Sandbox Code Playgroud)
并发送:
{
"operand1": 3,
"operand2": 5,
"multiplicationResult": 15,
/* other properties may come here */
}
Run Code Online (Sandbox Code Playgroud)
如果没有在我的类中明确映射它们,我如何隧道传递或传递我对此服务不感兴趣的消息的其他属性?
出于这种微服务的目的,它具有如下结构就足够了:
public class Task {
public double operand1;
public double operand2;
public double multiplicationResult;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我没有映射所有其他属性,它们将丢失.
如果我确实映射它们,那么每次消息结构发生变化时,我都必须更新这个微服务的模型,这需要付出努力并且容易出错.
假设我们有一个声明为的谓词Predicate<? super SomeClass>.我天真地期望它适用于SomeClass层次结构中的任何超类,包括Object.
但是这个谓词不适用于Object.我收到以下错误:
Predicate类型中的方法测试(捕获超级SomeClass的#3)不适用于参数(Object)
演示.
为什么Predicate<? super SomeClass>不适用于某个实例Object?
代码:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.URL;
import java.util.function.Predicate;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Predicate<? super URL> p = u -> u.getFile().isEmpty();
p.test(new Object());
}
}
Run Code Online (Sandbox Code Playgroud)