2013-04-28 7 views
2

J'ai appelé deux fois une méthode dans mon projet Java Android, mais je ne souhaite l'appeler qu'une seule fois. Lorsque j'appelle la méthode une seconde fois, je veux vérifier si la méthode a déjà été invoquée ou non. Le code est quelque chose comme ceci:Comment vérifier si une fonction est déjà appelée dans java?

class SomeClass { 
    //called with certain condition 
    private void a(){ 
     c(); //first call 
    } 

    private void b() { 
     c(); //second call,check here whether function is invoked already or not,if invoked not invoke here or vice-versa 
    } 

    //called with certain condition 
    private void c() { 

    } 
} 
+3

Est-ce Java ou JavaScript? –

+0

java pas javascript – Amrendra

+0

En utilisant le mot-clé 'function'? Ou est-ce censé être pseudo-code? –

Répondre

4

Vous devez utiliser un booléen (ou un compteur) pour enregistrer si la méthode a déjà été appelée. Mais comment vous le faites dépend de précisément ce que vous essayez de compter/limiter.

Ce qui suit suppose que vous utilisez un compteur:

  • Si vous voulez compter tous les appels à la méthode dans tous les contextes:

    private static int nos_calls; 
    
    public void function c() { 
        nos_calls += 1; 
        // do the call 
    } 
    
  • Si vous voulez juste compter les appels de la méthode pour un objet donné alors:

    private int nos_calls; 
    
    public void function c() { 
        nos_calls += 1; 
        // do the call 
    } 
    
  • Si vous voulez empêchent la méthode d'être appelé plus d'une fois:

    private int nos_calls; 
    
    public void function c() { 
        if (nos_calls++ == 0) { 
         // do the call 
        } 
    } 
    
  • Si la méthode pourrait être appelée à partir de fils différents, alors vous devez faire le comptage d'une manière qui se synchronise correctement; par exemple.

    private AtomicInteger nos_calls = new AtomicInteger(); 
    
    public void function c() { 
        if (nos_calls.incrementAndGet() == 1) { 
         // do the call 
        } 
    } 
    
  • Et ainsi de suite.

1

Vous pouvez faire quelque chose comme ceci:

class A{ 
    static boolean calledBefore = false; 
    public void a(){ 
    .... 
     c(); 
    } 
    public void b(){ 
    .... 
     c(); 
    } 
    public void c(){ 

     if(!calledBefore){ 
      //This will be executed if c() is not called before 
      //Do magic here 

      calledBefore = true; 
     } 
    } 
} 

calledBefore devrait être non statique si vous voulez avoir plusieurs instances de la classe A et chaque instance est autorisé à appeler c() une fois.

0

Vous pouvez ajouter un champ statique à la classe qui contient la fonction qui est modifiée dans la fonction (par exemple en l'incisant simplement) pour garder une trace des appels.

1

Si vous souhaitez exécuter une seule fois pendant toute la durée d'exécution du programme, utilisez une variable statique de classe. Si vous voulez exécuter une fois par objet ajouter un membre d'objet variable

class RunOnce { 
    private static boolean methodAHasRunOnce = false; 
    private boolean methodBHasRun = false; 

    public void methodA() { 
     if(RunOnce.methodAHasRunOnce) { return; } 
     System.out.println("Hello from methodA!"); 
     RunOnce.methodAHasRunOnce = true; 
    } 

    public void methodB() { 
     if(this.methodBHasRun) { return; } 
     System.out.println("Hello from methodB!"); 
     this.methodBHasRun = true; 
    } 
} 

courir maintenant:

RunOnce one = new RunOnce(); 
RunOnce two = new RunOnce(); 
one.methodA(); // Output: Hello from methodA! 
one.methodB(); // Output: Hello from methodB! 

one.methodA(); // No output 
one.methodB(); // No output 

two.methodA(); // No output 
two.methodB(); // Output: Hello from methodB! 

two.methodA(); // No output 
two.methodB(); // No output 
0

aspects seraient une solution générale à ce problème.Je ne suis absolument pas un expert par tout moyen (et cet exemple n'a pas été testé), mais ce serait quelque chose comme:

@Aspect 
public class CallOnlyOnceAspect { 

    @Pointcut("call(* methodThatShouldBeInvokedOnlyOnce(..))") 
    void methodThatShouldBeInvokedOnlyOnce() {} 

    @Around("methodThatShouldBeInvokedOnlyOnce()") 
    public Object preventMultipleCalls(ProceedingJoinPoint thisJoinPoint) { 
    // You need to implement this method for your particular methods/counters 
    if (hasAlreadyExecuted(thisJoinPoint)) { 
     return null; 
     // or equivalent return value, 
     // e.g. you may have cached the previous return value 
    } 
    Object result = thisJoinPoint.proceed(); 
    // Maybe cache result against thisJoinPoint 
    return result; 
    } 

} 

beaucoup plus de détails peuvent être trouvés dans ces endroits:

1

Je vois ici 2 solutions:

  1. Pour ce faire, vérification de l'état

public Clazz { 
    //private static boolean check = false; // if you want your method to be run once per class 
    private boolean check = false; // if you want your method to be run once per class instance 

    public void c() { 
     if(check) { 
      return; 
     } 
     check = true; 
     .... 
    } 

  1. Pour ce faire, l'interception des appels de méthode (par exemple proxies Java dynamiques, javassist, asm, etc.) ou en utilisant AOP

Mais vous devez avoir une interface pour cela:

public class TestInvocationHandler implements InvocationHandler { 

    //private static boolean check = false; 
    private boolean check = false; 

    private Object yourObject; 

    public TestInvocationHandler(Object object) { 
     yourObject = object; 
    } 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) 
     throws Throwable { 
     if(check) { 
      return null; // or whatever you need 
     } 
     check = true; 
     return method.invoke(yourObject, args); 
    } 
} 

et alors vous créer vos objets comme celui-ci:

ObjectInterface i = (ObjectInterface) Proxy.newProxyInstance(ObjectInterface.class.getClassLoader(), 
         new Class<?>[] {ObjectInterface .class}, 
         new TestInvocationHandler(new MyImplementingClass())); 
Questions connexes