J'ai un modèle de générateur dans lequel je prends quelques paramètres du client et base sur ce que je construis ma classe de constructeur, puis cette classe de constructeur est passée à notre bibliothèque sous-jacente et ma bibliothèque l'utilisera.Comment initialiser une variable dans le constructeur une seule fois?
public final class KeyHolder {
private final String clientId;
private final String deviceId;
private final int processId;
private final Cache<String, List<Response>> userCache;
private static final long MAXIMUM_CACHE_SIZE = 5000000;
private static final long EXPIRE_AFTER_WRITE = 120; // this is in seconds
private KeyHolder(Builder builder) {
this.clientId = builder.clientId;
this.deviceId = builder.deviceId;
this.processId = builder.processId;
this.maximumCacheSize = builder.maximumCacheSize;
this.expireAfterWrite = builder.expireAfterWrite;
// how to execute this line only once
this.userCache =
CacheBuilder
.newBuilder()
.maximumSize(maximumCacheSize)
.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
.removalListener(
RemovalListeners.asynchronous(new CustomListener(),
Executors.newSingleThreadScheduledExecutor())).build();
}
public static class Builder {
protected final int processId;
protected String clientId = null;
protected String deviceId = null;
protected long maximumCacheSize = MAXIMUM_CACHE_SIZE;
protected long expireAfterWrite = EXPIRE_AFTER_WRITE;
public Builder(int processId) {
this.processId = processId;
}
public Builder setClientId(String clientId) {
this.clientId = clientId;
return this;
}
public Builder setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public Builder setMaximumCacheSize(long size) {
this.maximumCacheSize = size;
return this;
}
public Builder setExpiryTimeAfterWrite(long duration) {
this.expireAfterWrite = duration;
return this;
}
public KeyHolder build() {
return new KeyHolder(this);
}
}
// getters here
}
Pour chaque appel à notre bibliothèque, ils créent une nouvelle classe à chaque fois constructeur KeyHolder
et le transmettre à notre bibliothèque. processId
, clientId
, deviceId
va changer à chaque appel mais maximumCacheSize
et expireAfterWrite
restera le même qu'à chaque appel. Comme vous pouvez le voir ci-dessus, j'utilise le cache de goyave ici et depuis qu'ils créent KeyHolder
classe de constructeur à chaque fois comment puis-je m'assurer que la ligne ci-dessous n'est exécutée qu'une seule fois dans mon constructeur?
this.userCache =
CacheBuilder
.newBuilder()
.maximumSize(maximumCacheSize)
.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
.removalListener(
RemovalListeners.asynchronous(new CustomListener(),
Executors.newSingleThreadScheduledExecutor())).build();
Depuis avec le code actuel en ce moment, il va s'exécuter à chaque appel et je vais obtenir un nouveau cache de goyave chaque fois dans ma bibliothèque pour tout ce qui a été mis en mémoire cache plus tôt l'entrée au sein de ma bibliothèque en utilisant ce cache goyave sera Foutez le camp.
Comment initialiser une variable particulière une seule fois et après cela, il devrait ignorer la valeur tout ce qui lui est passé?
Mise à jour: -
public class DataClient implements Client {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
// for synchronous call
@Override
public List<Response> executeSync(KeyHolder key) {
Cache<String, List<Response>> userCache = key.getUserCache();
List<Response> response = userCache.getIfPresent(key.getUUID());
if (CollectionUtils.isNotEmpty(response)) {
return response;
}
// if not in cache, then normally call the flow and populate the cache
List<Response> dataResponse = null;
Future<List<Response>> future = null;
try {
future = executeAsync(key);
dataResponse = future.get(key.getTimeout(), TimeUnit.MILLISECONDS);
userCache.put(key.getUUID(), dataResponse);
} catch (TimeoutException ex) {
// log error and return DataResponse
} catch (Exception ex) {
// log error and return DataResponse
}
return dataResponse;
}
}
Je suis confus, c'est déjà 'final' alors qu'entendez-vous par" * ignorez la valeur qui lui est transmise * "? Vous ne pouvez pas réinitialiser une variable 'final'. Pourriez-vous élaborer? –
@VinceEmigh It (userCache final) est une variable d'instance dans le code OP, pas statique –
@VinceEmigh mon cas d'utilisation est, client créer 'KeyHolder' classe chaque fois avec chaque appel, puis ils appellent notre bibliothèque en passant cela. Et maintenant ma bibliothèque utilise cette classe de construction et fait des bases supplémentaires sur les paramètres. J'ai édité ma question pour clarifier ceci plus. Maintenant que j'utilise le cache de goyave ici, je veux intiialzie ma base de cache de guava sur les valeurs transmises par le client mais je veux l'initialiser une seule fois. Et puis j'utilise ce cache de goyave dans ma bibliothèque comme indiqué dans mon code ci-dessus. – john