Parametre Olarak Java Geçiş Yöntemi


277

Referans olarak bir yöntem geçmek için bir yol arıyorum. Java'nın parametreleri parametre olarak geçirmediğini anlıyorum, ancak bir alternatif almak istiyorum.

Ben arayüzler parametre olarak geçen yöntemleri alternatif söylendi ama ben bir arayüz referans olarak bir yöntem olarak nasıl davranabilir anlamıyorum. Eğer doğru anlıyorsam, bir arayüz basitçe tanımlanmamış bir yöntem kümesidir. Birkaç farklı yöntem aynı parametrelerle aynı yöntemi çağırabildiğinden, her seferinde tanımlanması gereken bir arabirim göndermek istemiyorum.

Ne başarmak istiyorum buna benzer bir şeydir:

public void setAllComponents(Component[] myComponentArray, Method myMethod) {
    for (Component leaf : myComponentArray) {
        if (leaf instanceof Container) { //recursive call if Container
            Container node = (Container) leaf;
            setAllComponents(node.getComponents(), myMethod);
        } //end if node
        myMethod(leaf);
    } //end looping through components
}

çağrılan aşağıdaki gibi:

setAllComponents(this.getComponents(), changeColor());
setAllComponents(this.getComponents(), changeSize());

şu anda benim çözümüm ek bir parametre geçmek ve uygun yöntemi seçmek için içinde bir anahtar kutusu kullanmaktır. Ancak, bu çözüm yeniden kullanımı kodlamak için kredi vermez.

Benzer soru için bu cevaba da bakınız stackoverflow.com/a/22933032/1010868
Tomasz Gawel

Yanıtlar:


233

Düzenleme : Java 8'den itibaren, diğer cevapların işaret ettiği gibi lambda ifadeleri güzel bir çözümdür . Aşağıdaki cevap Java 7 ve öncesi için yazılmıştır ...


Komut desenine bir göz atın .

// NOTE: code not tested, but I believe this is valid java...
public class CommandExample 
{
    public interface Command 
    {
        public void execute(Object data);
    }

    public class PrintCommand implements Command 
    {
        public void execute(Object data) 
        {
            System.out.println(data.toString());
        }    
    }

    public static void callCommand(Command command, Object data) 
    {
        command.execute(data);
    }

    public static void main(String... args) 
    {
        callCommand(new PrintCommand(), "hello world");
    }
}

Düzenleme: Pete Kirkham'ın işaret ettiği gibi , bunu bir Ziyaretçi kullanarak yapmanın başka bir yolu var . Ziyaretçi yaklaşımı biraz daha karmaşıktır - düğümlerinizin bir acceptVisitor()yöntemle ziyaretçinin farkında olması gerekir - ancak daha karmaşık bir nesne grafiğini geçmeniz gerekiyorsa incelemeye değer.


2
@Mac - iyi! bu, onları simüle etmenin fiili yolu olarak birinci sınıf yöntemler olmadan dillerde tekrar tekrar ortaya çıkıyor, bu yüzden hatırlamaya değer.
Dan Vinton

7
Ziyaretçi kalıbıdır (bir koleksiyon üzerinde yineleme eylemini, koleksiyonun her üyesine uygulanan işlevden ayırın), komut kalıbı değil (bir nesneye yöntem çağrısı için bağımsız değişkenleri kapsülleyin). Özellikle argümanı kapsüllemiyorsunuz - bu, ziyaretçi modelinin yineleme kısmı tarafından sağlanmaktadır.
Pete Kirkham

Hayır, yalnızca çift gönderim ile ziyareti birleştiriyorsanız kabul yöntemine ihtiyacınız vardır. Monomorfik bir ziyaretçiniz varsa, tam olarak yukarıdaki kodunuzdur.
Pete Kirkham

Java 8'de ex.operS (String :: toLowerCase, "STRING") gibi olabilir. Güzel makaleye bakın: studytrails.com/java/java8/…
Zon

Pete Kirkham doğrudur: kodunuz Komut kalıbını değil Ziyaretçi kalıbını uyguluyor (ve OP'nin ihtiyaç duyduğu gibi bu iyi.) Pete'in söylediği gibi, argümanı kapsüllemiyorsunuz, bu yüzden Komut yapmıyorsunuz - Komutunuz arabiriminde parametre alan bir yürütme vardır. Wikipedia bunu yapmaz. Bu, Komut modelinin amacı için esastır. İlk paragrafın dediği gibi " tüm bilgileri kapsülleyin ... Bu bilgi, yöntem adını, yöntemin sahibi olan nesneyi ve yöntem parametreleri için değerleri içerir ."
ToolmakerSteve

73

Java 8'de artık Lambda İfadeleri ve Yöntem Referansları'nı kullanarak bir yöntemi daha kolay geçirebilirsiniz . İlk olarak, bazı arka plan: fonksiyonel bir arayüz, herhangi bir sayıda varsayılan yöntem içerebilmesine rağmen, bir ve sadece bir soyut yönteme sahip bir arayüzdür. (Java 8'de yeni) ve statik yöntemler . Bir lambda ifadesi, lambda ifadesi kullanmıyorsanız gerekli tüm sözdizimi olmadan soyut yöntemi hızlı bir şekilde uygulayabilir.

Lambda ifadeleri olmadan:

obj.aMethod(new AFunctionalInterface() {
    @Override
    public boolean anotherMethod(int i)
    {
        return i == 982
    }
});

Lambda ifadeleriyle:

obj.aMethod(i -> i == 982);

Lambda İfadeleri hakkındaki Java eğitiminden bir alıntı :

Lambda İfadelerinin Sözdizimi

Bir lambda ifadesi aşağıdakilerden oluşur:

  • Parantez içine alınmış resmi parametrelerin virgülle ayrılmış listesi. CheckPerson.test yöntemi, Person sınıfının bir örneğini temsil eden bir p parametresi içerir.

    Not : Lambda ifadesindeki parametrelerin veri türünü atlayabilirsiniz. Ayrıca, yalnızca bir parametre varsa parantezleri hariç tutabilirsiniz. Örneğin, aşağıdaki lambda ifadesi de geçerlidir:

    p -> p.getGender() == Person.Sex.MALE 
        && p.getAge() >= 18
        && p.getAge() <= 25
  • Ok belirteci, ->

  • Tek bir ifade veya ifade bloğundan oluşan bir gövde. Bu örnekte aşağıdaki ifade kullanılmaktadır:

    p.getGender() == Person.Sex.MALE 
        && p.getAge() >= 18
        && p.getAge() <= 25

    Tek bir ifade belirtirseniz, Java çalışma zamanı ifadeyi değerlendirir ve ardından değerini döndürür. Alternatif olarak, bir return ifadesi kullanabilirsiniz:

    p -> {
        return p.getGender() == Person.Sex.MALE
            && p.getAge() >= 18
            && p.getAge() <= 25;
    }

    Bir dönüş ifadesi bir ifade değildir; lambda ifadesinde ifadeleri parantez içine almalısınız ({}). Ancak, parantez içine bir boşluk yöntemi çağırma eklemek zorunda değilsiniz. Örneğin, aşağıdakiler geçerli bir lambda ifadesidir:

    email -> System.out.println(email)

Bir lambda ifadesinin yöntem beyanına çok benzediğini unutmayın; lambda ifadelerini isimsiz yöntemler olarak adlandırabilirsiniz.


Lambda ifadesini kullanarak "yöntemi" geçebilirsiniz:

interface I {
    public void myMethod(Component component);
}

class A {
    public void changeColor(Component component) {
        // code here
    }

    public void changeSize(Component component) {
        // code here
    }
}
class B {
    public void setAllComponents(Component[] myComponentArray, I myMethodsInterface) {
        for(Component leaf : myComponentArray) {
            if(leaf instanceof Container) { // recursive call if Container
                Container node = (Container)leaf;
                setAllComponents(node.getComponents(), myMethodInterface);
            } // end if node
            myMethodsInterface.myMethod(leaf);
        } // end looping through components
    }
}
class C {
    A a = new A();
    B b = new B();

    public C() {
        b.setAllComponents(this.getComponents(), component -> a.changeColor(component));
        b.setAllComponents(this.getComponents(), component -> a.changeSize(component));
    }
}

Sınıf C, aşağıdaki gibi yöntem başvuruları kullanılarak biraz daha kısaltılabilir:

class C {
    A a = new A();
    B b = new B();

    public C() {
        b.setAllComponents(this.getComponents(), a::changeColor);
        b.setAllComponents(this.getComponents(), a::changeSize);
    }
}

A sınıfının arayüzden miras alınması gerekiyor mu?
Serob_b

1
@Serob_b Hayır. Bir yöntem referansı olarak geçmek istemiyorsanız ( ::operatöre bakın ), A'nın ne olduğu önemli değildir. a.changeThing(component)geçersiz olduğu sürece istediğiniz ifadeye veya kod bloğuna değiştirilebilir.
Şapkalı Adam

29

java.lang.reflect.MethodNesneyi kullanın ve arayıninvoke


12
Ben neden görmüyorum. Soru, bir yöntemi bir parametre olarak geçirmektir ve bu çok geçerli bir yöntemdir. Bu, iyi görünmesi için herhangi bir sayıda güzel görünümlü desene de sarılabilir. Ve bu, herhangi bir özel arayüze ihtiyaç duymadan aldığı kadar geneldir.
Vinodh Ramasubramanian

3
JavaScript fg'de güvenlik yazdınız mı? Tip güvenliği bir argüman değildir.
Danubian Sailor

13
Söz konusu dil, tür güvenliğini en güçlü bileşenlerinden biri olarak tuttuğunda, tür güvenliği nasıl bir argüman değildir? Java, güçlü bir şekilde yazılmış bir dildir ve bu güçlü yazım, başka bir derlenmiş dilden seçmenizin nedenlerinden biridir.
Adam Parkin

21
"Çekirdek yansıma tesisi başlangıçta bileşen tabanlı uygulama oluşturucu araçları için tasarlanmıştır. [...] Kural olarak, çalışma zamanında normal uygulamalarda nesnelere yansıtılmamalıdır." Madde 53: Etkili Java Second Edition'dan arayüzleri yansımayı tercih edin. - Bu Java'nın yaratıcılarının düşünce
çizgisidir

8
Yansıtmanın makul bir kullanımı değildir. Ben tüm upvotes görmek için dehşete kapılmış. yansıtma asla genel bir programlama mekanizması olarak kullanılmak üzere tasarlanmamıştır; sadece başka temiz bir çözüm olmadığında kullanın.
ToolmakerSteve

22

Java 8'den beri yöntemi olan bir Function<T, R>arayüz ( dokümanlar ) var

R apply(T t);

Fonksiyonları parametre olarak diğer fonksiyonlara geçirmek için kullanabilirsiniz. T, işlevin giriş tipidir, R, dönüş tipidir.

Örneğinizde, Componenttürü girdi olarak alan ve hiçbir şey döndürmeyen bir işlevi iletmeniz gerekir - Void. Function<T, R>Void tipinde otomatik boks olmadığından, bu durumda en iyi seçim değildir. Aradığınız arayüze yöntemle Consumer<T>( dokümanlar ) denir

void accept(T t);

Şöyle görünecektir:

public void setAllComponents(Component[] myComponentArray, Consumer<Component> myMethod) {
    for (Component leaf : myComponentArray) {
        if (leaf instanceof Container) { 
            Container node = (Container) leaf;
            setAllComponents(node.getComponents(), myMethod);
        } 
        myMethod.accept(leaf);
    } 
}

Ve bunu yöntem referanslarını kullanarak çağırırsınız:

setAllComponents(this.getComponents(), this::changeColor);
setAllComponents(this.getComponents(), this::changeSize); 

Aynı sınıfta changeColor () ve changeSize () yöntemlerini tanımladığınızı varsayarsak.


Metodunuz birden fazla parametreyi kabul ederse, BiFunction<T, U, R>- T ve U giriş parametre tipleri ve R dönüş tipi olarak kullanabilirsiniz. Ayrıca var BiConsumer<T, U>(iki argüman, dönüş tipi yok). Ne yazık ki 3 ve daha fazla giriş parametresi için, kendiniz bir arayüz oluşturmanız gerekir. Örneğin:

public interface Function4<A, B, C, D, R> {

    R apply(A a, B b, C c, D d);
}

19

Öncelikle parametre olarak iletmek istediğiniz yöntemle bir Arayüz tanımlayın

public interface Callable {
  public void call(int param);
}

Yöntemle bir sınıf uygulama

class Test implements Callable {
  public void call(int param) {
    System.out.println( param );
  }
}

// Böyle çağır

Callable cmd = new Test();

Bu, cmd'yi parametre olarak iletmenizi ve arabirimde tanımlanan yöntem çağrısını çağırmanızı sağlar

public invoke( Callable callable ) {
  callable.call( 5 );
}

1
Java sizin için çok şey tanımladığı için kendi arayüzünüzü yapmak zorunda kalmayabilirsiniz
ince

@slim İlginç bir nokta, bu tanımlar ne kadar kararlı, önerdiğiniz gibi alışılmış olarak mı kullanılmalı, yoksa kırılma ihtimali var mı?
Manuel

@slim Aslında dokümanlar şu yanıtı veriyor: "Bu paketteki arabirimler JDK tarafından kullanılan genel amaçlı işlevsel arabirimlerdir ve kullanıcı kodu tarafından da kullanılabilir."
Manuel

14

Bu henüz Java 7 ve altı için geçerli olmasa da, geleceğe bakmamız ve en azından değişiklikleri tanımamız gerektiğine inanıyorum. Java 8 gibi yeni sürümlerde gelecek .

Yani, bu yeni sürüm, Java'ya lambdas ve yöntem referansları getiriyor ( yeni API'lerle birlikte) bu soruna başka bir geçerli çözüm olan . Hala bir arabirim gerektirmesine rağmen yeni nesneler oluşturulmuyor ve ekstra sınıf dosyaları farklı nedenlerle çıkış dizinlerini kirletmek zorunda kalmıyor JVM tarafından elleçleme.

Her iki aroma (lambda ve yöntem referansı) imzası kullanılan tek bir yöntemle kullanılabilen bir arayüz gerektirir:

public interface NewVersionTest{
    String returnAString(Object oIn, String str);
}

Yöntemlerin isimleri bundan sonra önemli olmayacak. Bir lambda kabul edildiğinde, bir yöntem referansı da geçerlidir. Örneğin, imzanızı burada kullanmak için:

public static void printOutput(NewVersionTest t, Object o, String s){
    System.out.println(t.returnAString(o, s));
}

Bu sadece basit bir arayüz çağrısı, lambda 1 geçene kadar :

public static void main(String[] args){
    printOutput( (Object oIn, String sIn) -> {
        System.out.println("Lambda reached!");
        return "lambda return";
    }
    );
}

Bu çıktı:

Lambda reached!
lambda return

Yöntem referansları benzerdir. Verilen:

public class HelperClass{
    public static String testOtherSig(Object o, String s){
        return "real static method";
    }
}

ve ana:

public static void main(String[] args){
    printOutput(HelperClass::testOtherSig);
}

çıktı olurdu real static method. Yöntem başvuruları statik, örnek, rasgele örneklerle statik olmayan ve hatta yapıcılar olabilir . Yapıcı için benzer bir şey ClassName::newkullanılacaktı.

1 Bu, bazı yan etkileri olduğu için bazıları tarafından lambda olarak kabul edilmez. Bununla birlikte, birinin görselleştirilmesi daha basit bir şekilde kullanımını göstermektedir.


12

En son kontrol ettiğimde, Java istediğinizi yerel olarak yapamaz; bu tür sınırlamaları aşmak için 'geçici çözümler' kullanmanız gerekir. Gördüğüm kadarıyla, arayüzler bir alternatiftir, ancak iyi bir alternatif değildir. Belki de size bunun böyle bir şey ifade ettiğini söyleyen:

public interface ComponentMethod {
  public abstract void PerfromMethod(Container c);
}

public class ChangeColor implements ComponentMethod {
  @Override
  public void PerfromMethod(Container c) {
    // do color change stuff
  }
}

public class ChangeSize implements ComponentMethod {
  @Override
  public void PerfromMethod(Container c) {
    // do color change stuff
  }
}

public void setAllComponents(Component[] myComponentArray, ComponentMethod myMethod) {
    for (Component leaf : myComponentArray) {
        if (leaf instanceof Container) { //recursive call if Container
            Container node = (Container) leaf;
            setAllComponents(node.getComponents(), myMethod);
        } //end if node
        myMethod.PerfromMethod(leaf);
    } //end looping through components
}

Hangisini daha sonra çağırırsınız:

setAllComponents(this.getComponents(), new ChangeColor());
setAllComponents(this.getComponents(), new ChangeSize());

6

Bir şey döndürmek için bu yöntemlere ihtiyacınız yoksa, Runnable nesnelerini döndürmelerini sağlayabilirsiniz.

private Runnable methodName (final int arg) {
    return (new Runnable() {
        public void run() {
          // do stuff with arg
        }
    });
}

Sonra şöyle kullanın:

private void otherMethodName (Runnable arg){
    arg.run();
}

2

java.util.function.FunctionParametre işlevi olarak basit yöntem için nasıl kullanılacağı konusunda benim için yeterince açık bir örnek bulamadım . İşte basit bir örnek:

import java.util.function.Function;

public class Foo {

  private Foo(String parameter) {
    System.out.println("I'm a Foo " + parameter);
  }

  public static Foo method(final String parameter) {
    return new Foo(parameter);
  }

  private static Function parametrisedMethod(Function<String, Foo> function) {
    return function;
  }

  public static void main(String[] args) {
    parametrisedMethod(Foo::method).apply("from a method");
  }
}

Temel olarak Foovarsayılan bir yapıcıya sahip bir nesneniz vardır. A tipi methodparametre olarak çağrılacaktır .parametrisedMethodFunction<String, Foo>

  • Function<String, Foo>, işlevin bir Stringas parametresini alıp a değerini döndürdüğü anlamına gelir Foo.
  • Foo::MethodGibi bir lambda tekabülx -> Foo.method(x);
  • parametrisedMethod(Foo::method) olarak görülebilir x -> parametrisedMethod(Foo.method(x))
  • .apply("from a method")Yapmak temeldeparametrisedMethod(Foo.method("from a method"))

Hangi daha sonra çıktı geri döner:

>> I'm a Foo from a method

Örnek olduğu gibi çalışıyor olmalı, daha sonra farklı sınıflar ve arayüzlerle yukarıdaki cevaplardan daha karmaşık şeyler deneyebilirsiniz.


android uygulama çağrısı kullanmak için bir minimum api 24 gerekir
Ines Belhouchet

1

Java'nın adı iletmek ve çağırmak için bir mekanizması var. Yansıma mekanizmasının bir parçasıdır. İşleviniz, Yöntem sınıfının ek parametresini almalıdır.

public void YouMethod(..... Method methodToCall, Object objWithAllMethodsToBeCalled)
{
...
Object retobj = methodToCall.invoke(objWithAllMethodsToBeCalled, arglist);
...
}

1

Bir java uzmanı değilim ama sorununuzu şu şekilde çözüyorum:

@FunctionalInterface
public interface AutoCompleteCallable<T> {
  String call(T model) throws Exception;
}

Parametreyi özel Arayüzümde tanımlıyorum

public <T> void initialize(List<T> entries, AutoCompleteCallable getSearchText) {.......
//call here
String value = getSearchText.call(item);
...
}

Son olarak, initialize yöntemini çağırırken getSearchText yöntemini uyguluyorum .

initialize(getMessageContactModelList(), new AutoCompleteCallable() {
          @Override
          public String call(Object model) throws Exception {
            return "custom string" + ((xxxModel)model.getTitle());
          }
        })

Aslında en iyi cevap ve bunu yapmanın doğru yolu. Daha fazla +1
hak ediyor

0

Gözlemci desenini kullanın (bazen Dinleyici deseni de denir):

interface ComponentDelegate {
    void doSomething(Component component);
}

public void setAllComponents(Component[] myComponentArray, ComponentDelegate delegate) {
    // ...
    delegate.doSomething(leaf);
}

setAllComponents(this.getComponents(), new ComponentDelegate() {
                                            void doSomething(Component component) {
                                                changeColor(component); // or do directly what you want
                                            }
                                       });

new ComponentDelegate()... arabirimi uygulayan anonim bir tür bildirir.


8
Bu aradığınız kalıp değil.
Pete Kirkham

1
Gözlemci örüntüsü, bir değişikliğe tepki verme yeteneğini soyutlamakla ilgilidir. OP, bir koleksiyondaki her öğede, ziyaretçi modeli olan koleksiyon üzerinde yinelenen koddan uzakta gerçekleştirilen eylemi özetlemek ister.
Pete Kirkham

Gözlemci / Dinleyici kalıbı aslında bu Komut kalıbıyla aynıdır. Sadece niyet açısından farklılık gösterirler. Komut birinci sınıf fonksiyonların / lambdas'ın yerini alırken gözlemci bildirim ile ilgilidir. Ziyaretçi ise tamamen farklı bir şey. Birkaç cümle ile açıklanabileceğini sanmıyorum, bu yüzden lütfen en.wikipedia.org/wiki/Visitor_pattern
EricSchaefer

0

İşte temel bir örnek:

public class TestMethodPassing
{
    private static void println()
    {
        System.out.println("Do println");
    }

    private static void print()
    {
        System.out.print("Do print");
    }

    private static void performTask(BasicFunctionalInterface functionalInterface)
    {
        functionalInterface.performTask();
    }

    @FunctionalInterface
    interface BasicFunctionalInterface
    {
        void performTask();
    }

    public static void main(String[] arguments)
    {
        performTask(TestMethodPassing::println);
        performTask(TestMethodPassing::print);
    }
}

Çıktı:

Do println
Do print

0

Burada bir yöntemin bir parametresi olarak kendisine bağlı parametreleri ile yöntemi geçmek gösteren herhangi bir çözüm bulamadım. Körük, bir parametreyi zaten bağlı olan parametre değerleriyle nasıl geçirebileceğinize bir örnektir.

  1. Adım 1: Biri dönüş tipi, diğeri olmayan iki arabirim oluşturun. Java'nın benzer arayüzleri vardır, ancak istisna atmayı desteklemedikleri için pratik kullanımları azdır.


    public interface Do {
    void run() throws Exception;
    }


    public interface Return {
        R run() throws Exception;
    }
  1. İşlem sırasında yöntem çağrısını sarmak için her iki arabirimi nasıl kullandığımızın örneği. Yöntemi gerçek parametrelerle geçirdiğimizi unutmayın.


    //example - when passed method does not return any value
    public void tx(final Do func) throws Exception {
        connectionScope.beginTransaction();
        try {
            func.run();
            connectionScope.commit();
        } catch (Exception e) {
            connectionScope.rollback();
            throw e;
        } finally {
            connectionScope.close();
        }
    }

    //Invoke code above by 
    tx(() -> api.delete(6));

Başka bir örnek, aslında bir şey döndüren bir yöntemin nasıl geçirileceğini gösterir



        public  R tx(final Return func) throws Exception {
    R r=null;
    connectionScope.beginTransaction();
    try {
                r=func.run();
                connectionScope.commit();
            } catch (Exception e) {
                connectionScope.rollback();
                throw e;
            } finally {
                connectionScope.close();
            }
        return r;
        }
        //Invoke code above by 
        Object x= tx(() -> api.get(id));

0

Yansımalı çözüm örneği, geçirilen yöntem herkese açık olmalıdır

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public class Program {
    int i;

    public static void main(String[] args) {
        Program   obj = new Program();    //some object

        try {
            Method method = obj.getClass().getMethod("target");
            repeatMethod( 5, obj, method );
        } 
        catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            System.out.println( e ); 
        }
    }

    static void repeatMethod (int times, Object object, Method method)
        throws IllegalAccessException, InvocationTargetException {

        for (int i=0; i<times; i++)
            method.invoke(object);
    }
    public void target() {                 //public is necessary
        System.out.println("target(): "+ ++i);
    }
}

0

Yukarıdaki cevapları takdir ediyorum ama aynı yöntemi aşağıdaki yöntemi kullanarak elde edebildim; Javascript geri aramalarından alınan bir fikir. Şu ana kadar düzeltmeye açıkım (üretimde).

Fikir, imzadaki fonksiyonun dönüş tipini kullanmaktır, yani verimin statik olması gerekir.

Aşağıda, zaman aşımı olan bir işlemi çalıştıran bir işlev bulunmaktadır.

public static void timeoutFunction(String fnReturnVal) {

    Object p = null; // whatever object you need here

    String threadSleeptime = null;

    Config config;

    try {
        config = ConfigReader.getConfigProperties();
        threadSleeptime = config.getThreadSleepTime();

    } catch (Exception e) {
        log.error(e);
        log.error("");
        log.error("Defaulting thread sleep time to 105000 miliseconds.");
        log.error("");
        threadSleeptime = "100000";
    }

    ExecutorService executor = Executors.newCachedThreadPool();
    Callable<Object> task = new Callable<Object>() {
        public Object call() {
            // Do job here using --- fnReturnVal --- and return appropriate value
            return null;
        }
    };
    Future<Object> future = executor.submit(task);

    try {
        p = future.get(Integer.parseInt(threadSleeptime), TimeUnit.MILLISECONDS);
    } catch (Exception e) {
        log.error(e + ". The function timed out after [" + threadSleeptime
                + "] miliseconds before a response was received.");
    } finally {
        // if task has started then don't stop it
        future.cancel(false);
    }
}

private static String returnString() {
    return "hello";
}

public static void main(String[] args) {
    timeoutFunction(returnString());
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.