java - 调整作为单例且具有最终访问修饰符的方法的返回值
问题描述
我想从实例类调整方法的返回值,我不太确定是否可以使用或不使用反射。我想不通,所以我想在这里问。假设我有例如以下类 Foo:
public final class Foo {
private static final INSTANCE = new Foo()
protected Foo() {}
public final String getName() {
return "Foo";
}
public static Foo getInstance() {
return INSTANCE;
}
}
一些上下文:
- Foo 类来自外部库
- Foo 类不可调整
- Foo 类不可扩展
因此,对于这个基本示例,我想从方法 getName() 而不是Foo返回Bar。要非常明确:
Foo foo = Foo.getInstance();
String name = foo.getName();
System.out.println(name) // --> prints "Bar"
为什么我需要这个?
好吧,我需要将 Foo 的这个实例传递给另一个只接受 Foo 类型的对象的方法。此方法将调用方法 getName() 并进行一些额外的计算。
实际用例:
我将尝试提供更多上下文,希望它会更清楚一点。构建器类中有一个方法,它接受一个KeyManagerFactory
名为 的方法的实例setKeyManagerFactory(KeyManagerFactory keyManagerFactory)
。此构建器类将在内部调用getKeyManagers
KeyManagerFactory 并将返回KeyManagers[]
KeyManagerFactory 是最终类,它根本没有公共构造函数。getKeyManager 方法也是最终的。我已经有一个KeyManager[]
,所以我想破解这个 KeyManagerFactory 来返回我自己的数组自己的 KeyManagers 并将其提供给构建器。
通常 KeyManagerFactory 使用以下代码片段进行实例化:
KeyStore keyStore = ... //initialized keyStore
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
kmf.init(keyStore, keyPassword);
KeyManager[] keyManagers = kmf.getKeyManagers();
使用上面的代码片段,KeyManagerFactory 将根据提供的 KeyStore 对象返回一个 KeyManager 数组。我想要实现的是以某种方式返回我的自定义 KeyManager 数组。
我还添加了 KeyManagerFactory 的反编译源代码:
package javax.net.ssl;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import sun.security.jca.GetInstance;
import sun.security.jca.GetInstance.Instance;
public class KeyManagerFactory {
private Provider provider;
private KeyManagerFactorySpi factorySpi;
private String algorithm;
public static final String getDefaultAlgorithm() {
String var0 = (String)AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return Security.getProperty("ssl.KeyManagerFactory.algorithm");
}
});
if (var0 == null) {
var0 = "SunX509";
}
return var0;
}
protected KeyManagerFactory(KeyManagerFactorySpi var1, Provider var2, String var3) {
this.factorySpi = var1;
this.provider = var2;
this.algorithm = var3;
}
public final String getAlgorithm() {
return this.algorithm;
}
public static final KeyManagerFactory getInstance(String var0) throws NoSuchAlgorithmException {
Instance var1 = GetInstance.getInstance("KeyManagerFactory", KeyManagerFactorySpi.class, var0);
return new KeyManagerFactory((KeyManagerFactorySpi)var1.impl, var1.provider, var0);
}
public static final KeyManagerFactory getInstance(String var0, String var1) throws NoSuchAlgorithmException, NoSuchProviderException {
Instance var2 = GetInstance.getInstance("KeyManagerFactory", KeyManagerFactorySpi.class, var0, var1);
return new KeyManagerFactory((KeyManagerFactorySpi)var2.impl, var2.provider, var0);
}
public static final KeyManagerFactory getInstance(String var0, Provider var1) throws NoSuchAlgorithmException {
Instance var2 = GetInstance.getInstance("KeyManagerFactory", KeyManagerFactorySpi.class, var0, var1);
return new KeyManagerFactory((KeyManagerFactorySpi)var2.impl, var2.provider, var0);
}
public final Provider getProvider() {
return this.provider;
}
public final void init(KeyStore var1, char[] var2) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
this.factorySpi.engineInit(var1, var2);
}
public final void init(ManagerFactoryParameters var1) throws InvalidAlgorithmParameterException {
this.factorySpi.engineInit(var1);
}
public final KeyManager[] getKeyManagers() {
return this.factorySpi.engineGetKeyManagers();
}
}
解决方案
你可以这样做。(您可以将 setAccessible(true) 用于私有字段)
public final class Single {
public String s;
public Single() {
}
public String getS() {
return s;
}
}
public class Main {
public static void main(String[] args) throws IllegalAccessException {
Single single = new Single();
single.getClass().getFields()[0].set(single, "Hmm");
System.out.println(single.getS());
}
}
推荐阅读
- python-3.x - 来自 Active Directory 的 Python ldap3 缩略图
- angular - 使用 canActivate 确定显示链接
- c# - '/usr/bin/python3: 在 Raspberry Pi 上使用单声道执行 .exe 文件时无法打开文件'test.py''
- r - 两个等长向量的逐元素比较
- flowtype - 优化数组类型的联合
- python - 了解 google ai 平台自定义预测例程的输入
- c# - 测试方法通过指南
- oracle - 如何使 SQLPlus 编译警告静音?
- python - 识别字符串中括号中的表情符号
- progressive-web-apps - PWA - 将 manifest.json 更改为无法找到的 site.webmanifest