小编lex*_*ore的帖子

添加参数后,覆盖具有泛型返回类型的方法失败

我想知道为什么这是一个有效的覆盖:

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的签名的子签名,如果:

  • m2与m1具有相同的签名,或
  • m1的签名与m2签名的擦除(§4.6)相同.

因此它似乎B.getSupplier …

java generics overriding

17
推荐指数
1
解决办法
234
查看次数

Spring Cache刷新过时的值

在基于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() …

java spring caching

16
推荐指数
2
解决办法
5043
查看次数

创建一个常见的xsd生成类,供其他包使用

我试图使用相同的生成类,但在单独的包中.所以结构看起来应该是这样的:

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)

xsd jaxb xjc maven-jaxb2-plugin

15
推荐指数
2
解决办法
2万
查看次数

有没有办法在Java中为一个类"别名"另一个?

我有以下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.SomeEnumcom.acme.bar.SomeEnum?这将允许旧插件继续使用新版本的工具.

一些类加载器技巧?在JavaScript中,对于垫片来说是微不足道的,但是在Java中?

为什么这么问.我是Maven插件的作者,它包含了有问题的工具.因此,我可以轻松地将糖添加到这种咖啡中,就像类加载器一样.如果有技术方法可以完成这项工作,那么我将能够保存大部分工具的插件生态系统 - 至少对于Maven用户而言.

我已经联系过该工具的供应商,但不确定是否成功.

只是要清楚- 不是有问题的工具的供应商.我(a)为The Tools编写插件(并且更新我的插件没有大麻烦)和(b)是the-tool-maven-plugin允许在Maven构建中执行The Tool 的作者.我还对The Tool进行了很多咨询并关注它的生态系统(有很多非常有用的插件).


更新

故事结束:The Tool的开发人员将我的观点考虑在内,并决定恢复变更.为此感到荣幸!

java

14
推荐指数
1
解决办法
1112
查看次数

如何以编程方式从pom.xml执行特定的插件/ Mojo?

我是其中一个Maven插件的作者(不是Apache/Codehaus,完全独立).有时我得到支持请求或测试用例,我真的需要用现有的调试插件的执行pom.xml.基本上我得到的测试用例是样本/测试项目(pom.xmlsrc/main/resoures,src/main/java等等).

我需要的是一种方法:

  • 加载现有的pom.xml.
  • 在那里找到我的插件的特定执行(通常它是唯一的).
  • 获取一个实例MyMojo- 完全初始化/配置,并注入所有组件和参数.
  • 执行MyMojo.
  • 重要的是测试项目是单独的项目,我不想将它们复制到我的插件的Maven模块中.
  • 我希望能够在没有远程调试的情况下完成此操作.

通过调试我的意思是能够设置和停止断点(也是有条件的),在源代码上进/出/结束.

理想情况下,我希望能够executeMyMojoFrom(new File("pom.xml"))- 例如在JUnit测试或main某个类的方法中.(我可以提供groupId,artifactId等等.所有其他的定义应该只从装pom.xml).

我怎样才能做到这一点?


到目前为止我尝试过的:

  • Debug As...pom.xmlEclipse中-不工作不够好(源代码没有找到,断点不作为它不是一个Java项目环境中工作)
  • Maven Embedder/Invoker解决方案 - 通过CLI在单独的进程中生成东西.忘记断点,没有调试.
  • 远程调试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)

java maven-plugin maven

14
推荐指数
1
解决办法
1021
查看次数

通过JavaScript可靠地更改浏览器历史记录中的页面标题

是否可以在加载页面后通过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 google-chrome browser-history angularjs

12
推荐指数
1
解决办法
2136
查看次数

模块化JavaScript - 除了CommonJS和AMD之外还有其他方法可以考虑吗?

我正在为我的公司准备评估JavaScript模块化方法.我们正在为我们的项目定义"JavaScript最佳实践",模块化是一个核心问题.

从我迄今为止的研究中发现了两种主要方法:

周围有大量的加载器,插件,库等.

除此之外,还有goog.provide/ goog.require来自Google Closure Library.

还有其他方法需要考虑吗?我错过了哪些重要/相关的规格?

我们的要求简要说明:

  • 在单独的文件中构建JavaScript代码.
  • 在运行时加载相关模块.
  • ...不必将每个文件都包含在脚本标记中.
  • 一定不能维护JavaScript文件的索引.
  • 支持聚合和缩小 - 构建和使用单个缩小/优化的JavaScript文件的能力.
  • 能够以不同的组合使用模块 - 通常有不同的网页/客户端需要不同的模块子集.
  • 支持文档(使用JSDoc?).
  • 适合测试.
  • 适用于网络,跨浏览器.
  • 合理的IDE支持.

潜在:

  • 与ES6模块对齐.
  • 适用于Node.js和移动平台(如PhoneGap/Cordova).

答案的新建议:


附注:

  • 问题在于哪种方法更好.
  • 我不是要求特定的库和工具,而是要求方法和规范.
  • 我并没有特别要求提供场外资源.(如果没有这样的SO标签,我们考虑它可能是不合理的.)
  • 关于等框架的说明.这不是真正适合这个问题的框架.如果项目需要一个框架(无论是AngularJS还是ExtJS),那么大多数都没有模块化问题,因为框架必须提供模块化OOTB.如果项目不需要框架,那么由于模块化而带来框架是一种过度的做法.这是我特别没有询问库/工具的原因之一.

javascript amd modular modularization commonjs

11
推荐指数
1
解决办法
873
查看次数

是否向后兼容用像Wild <?>这样的通配符替换像Collection这样的原始类型?

我是某个开源库的作者.其中一个公共接口具有使用原始类型的方法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<?>.

但是,这些方法是我的库的公共接口的一部分.客户端代码可以调用这些方法或提供这些公共接口的自己实现,从而实现这些方法.我担心更改CollectionCollection<?>会破坏客户端代码.所以这是我的问题.

如果我在公共接口中更改Collection- > Collection<?>,可能会导致:

  • 客户端代码中的编译错误?
  • 已编译的现有客户端代码中的运行时错误?

java generics

11
推荐指数
2
解决办法
349
查看次数

如何使用Jackson和MongoDB传递JSON消息中的属性?

我们有一个微服务,它从队列中获取一些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)

但是,如果我没有映射所有其他属性,它们将丢失.

如果我确实映射它们,那么每次消息结构发生变化时,我都必须更新这个微服务的模型,这需要付出努力并且容易出错.

java spring json jackson microservices

10
推荐指数
2
解决办法
1153
查看次数

为什么Predicate <?super SomeClass>不适用于Object?

假设我们有一个声明为的谓词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)

java generics

10
推荐指数
1
解决办法
1418
查看次数