Eu preciso de um "Runnable que aceite um parâmetro", embora eu saiba que esse executável não existe realmente.
Isso pode apontar para uma falha fundamental no design do meu aplicativo e / ou um bloqueio mental no meu cérebro cansado, por isso espero encontrar aqui alguns conselhos sobre como realizar algo como o seguinte, sem violar os princípios fundamentais de OO:
private Runnable mOneShotTask = new Runnable(String str) {
public void run(String str) {
someFunc(str);
}
};
Alguma idéia de como realizar algo como o acima?
Consumer<T>
.Consumer<T>
Respostas:
Bem, já faz quase 9 anos desde que eu postei isso originalmente e, para ser sincero, o Java fez algumas melhorias desde então. Deixarei minha resposta original abaixo, mas não há necessidade de as pessoas fazerem o que está nele. Há 9 anos, durante a revisão de código, eu teria questionado por que eles fizeram e talvez tenham aprovado, talvez não. Com as lambdas modernas disponíveis, é irresponsável ter uma resposta tão votada recomendando uma abordagem antiquada (que, com toda a justiça, era duvidosa para começar ...) No Java moderno, essa revisão de código seria imediatamente rejeitada, e isso seria sugerido:
Como antes, detalhes como lidar com esse tópico de maneira significativa são deixados como um exercício para o leitor. Mas, para ser franco, se você tem medo de usar lambdas, deve ter ainda mais medo de sistemas multiencadeados.
Resposta original, apenas porque:
Você pode declarar uma classe diretamente no método
fonte
Você poderia colocá-lo em uma função.
(Quando eu usei isso, meu parâmetro era um ID inteiro, que eu usei para criar um hashmap de ID -> myRunnables. Dessa forma, eu posso usar o hashmap para postar / remover diferentes objetos myRunnable em um manipulador.)
fonte
Runnable
objeto retornado pelo método existir em qualquer lugar,paramStr
provavelmente não será elegível para a coleta de lixo. É possível que, se o objeto existir, mas nunca puder ser executado novamente, o JIT (ou mesmo o javac) decida removê-lo do escopo, mas não devemos confiar nessas otimizações, pois elas podem mudar no futuro.Crie a função init que retorna o próprio objeto e inicialize os parâmetros com ele.
fonte
Eu uso a seguinte classe que implementa a interface Runnable . Com essa classe, você pode criar facilmente novos threads com argumentos
fonte
public RunnableArg(Object... args) { setArgs(args); }
depois descrever a classe local:class ActionArg extends RunnableArg { public ActionArg(Object... arg) { super(arg); } @Override public void run() { /* getArgs() and process them */ } }
e usá-loThread t = new Thread(new ActionArg( %param_object(s)% )); t.start();
Você tem duas opções:
Defina uma classe nomeada. Passe seu parâmetro para o construtor da classe nomeada.
Faça com que sua classe anônima feche seu "parâmetro". Certifique-se de marcar como
final
.fonte
Desde o Java 8, a melhor resposta é usar
Consumer<T>
:https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html
É uma das interfaces funcionais, o que significa que você pode chamá-lo como uma expressão lambda:
fonte
Gostaria primeiro de saber o que você está tentando realizar aqui para precisar que um argumento seja passado para o novo Runnable () ou run (). A maneira usual deve ser ter um objeto Runnable que transmita dados (str) para seus threads definindo variáveis de membros antes de iniciar. O método run () usa esses valores de variável de membro para executar someFunc ()
fonte