![](/img/trans.png)
[英]Java: Binary Search Implementation not working using Deferred detection of equality
[英]Is there a way to call a deferred implementation in Java?
我不确定这里的术语是否完全正确。
我有一个 class 和一些 static 方法,这些方法在很久以前编写的一些库代码中被其他几个类调用。
class 与 static 方法(由其他几个类调用)具有对第三方 class 的引用,该第三方现在具有版本 2。
有没有办法我可以编写这个 class 来执行类似“当调用这个 static 方法时,你需要调用一些东西来查看你应该使用哪个版本的库”?
这样,当我将此库代码作为 jar 文件拉入新项目时,我可以在每个项目中包含一些内容,这些内容将告诉库中的 class 使用特定版本的 static 方法。
这样我就不需要为我的库中的每个类提供 version1 和 version2。
我是否在延期的正确轨道上?
lambda function 也许?
您的问题有几种不同的解决方案,具体取决于您的第三方库的更改方式。
我假设您的第三方 class 的第 2 版具有您需要的第 1 版中没有的新方法?
最简单的解决方案是针对库的版本 2 实施 class,但处理LinkageError (或更具体的子类,例如NoSuchMethodError ),如果捕获到这些错误,则恢复到版本 1 调用。 如果它是完全不同的 class,您也可以通过处理NoClassDefFoundError来处理。
或者,如果性能不重要,您也可以使用反射。
有点。 Java 不会加载 class ,除非您确实需要它。 这意味着您可以执行以下操作:
public String getFoo() {
switch (versionRequired()) {
case 1: return new Version1Impl().getFoo();
default: return new Version2Impl().getFoo();
}
}
boolean versionRequired() {
// figure out which version is needed here.
// if you're having trouble with this, you can use `Class.forName` to check
// if a certain type is even available. Worst case scenario, you can
// ask a class for its own bytecode and hash that. This is very tricky.
return 1;
}
private static class Version1Impl {
public String getFoo() {
return new UseSomethingFromV1().getFoo();
}
}
这里奇怪的“重定向到内部类”的线索是内部 class 在切换分支被采用之前不会被加载,只要例如Version2Impl
永远不会加载,你也永远不会得到它所指的错误到不存在的 class (因为它是为该库的 v2 设计的,但只有 v1 可用)。
注意:关于那个版本检测方案:散列类的问题是 class 可能在 2 个主要版本之间没有变化(你希望它不同,但它不会)。 或者,另一方面,一个次要的版本更新可能已经改变了它(它现在不同了,但你不希望它如此)。 一个解决方案是 hash 很多类,这有助于第一种情况(您想注意更改),但会使第二种情况更糟。 您可以使用例如try (InputStream in = String.class.getResourceAsStream("String.class")) {
- 适用于任何 class。 通过哈希器折腾这个输入流(如果你不知道如何搜索 web,这是一个非常常见的任务,有很多教程可以找到)。
许多库都有一种受支持的方式来询问它们是什么版本,但没有标准,因此请查看该库的文档。
现在,我已经创建了一个基于文件的解决方案。 在 class 路径上查找文件,如果存在,请从文件中读取指示的版本。 如果没有文件,请使用默认(原始)版本。
package com.nach.core.util.fhir.parser;
import java.io.File;
import org.hl7.fhir.instance.model.api.IBaseResource;
import com.nach.core.util.file.FileUtil;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FhirJsonParser {
private static final FhirContext CTX;
private static final IParser PARSER;
static {
File fhirContextFile = FileUtil.getFile("/fhir-context.txt");
if (fhirContextFile != null && fhirContextFile.exists()) {
String fhirContext = FileUtil.getAsString(fhirContextFile).trim();
if ("Dstu3".equals(fhirContext)) {
log.info("USING DSTU3 FOR FHIR PARSING");
CTX = FhirContext.forDstu3();
} else if ("R4".equals(fhirContext)) {
log.info("USING R4 FOR FHIR PARSING");
CTX = FhirContext.forR4();
} else {
CTX = FhirContext.forDstu3();
}
} else {
CTX = FhirContext.forDstu3();
}
PARSER = CTX.newJsonParser();
}
/**
* Generate a class from a json string.
*/
public static <T extends IBaseResource> T parse(String jsonString, Class<T> cls) {
try {
IParser parser = CTX.newJsonParser();
parser.setStripVersionsFromReferences(false);
CTX.getParserOptions().setStripVersionsFromReferences(false);
IParser jsonParser = CTX.newJsonParser();
T rtn = jsonParser.parseResource(cls, jsonString);
return rtn;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
/**
* Generate a json string from a class.
*/
public static String serialize(IBaseResource resource) {
String rtn = PARSER.encodeResourceToString(resource);
return rtn;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.