2008-09-26 16 views

Odpowiedz

21

Tak. Java 1.7 wprowadzono konstrukt try-with-resources pozwalającą Ci napisać:

try(InputStream is1 = new FileInputStream("/tmp/foo"); 
    InputStream is2 = new FileInputStream("/tmp/bar")) { 
     /* do stuff with is1 and is2 */ 
} 

... niczym using oświadczeniu.

Niestety, przed wersją Java 1.7, programiści Java zmuszeni byli użyć try {...} finally {...}. W języku Java 1.6:

InputStream is1 = new FileInputStream("/tmp/foo"); 
try{ 

    InputStream is2 = new FileInputStream("/tmp/bar"); 
    try{ 
     /* do stuff with is1 and is 2 */ 

    } finally { 
     is2.close(); 
    } 
} finally { 
    is1.close(); 
} 
+0

Czy jest możliwe zaktualizowanie tej odpowiedzi na przykładzie C# z wykorzystaniem bloku, a następnie Java z wypróbowaniem na końcu? Najlepiej jest, gdy korzystamy z 2 oddzielnych zasobów, aby udokumentować, jak upewnić się, że wszystko jest poprawnie zamknięte. –

+2

Jako facet w języku Java powyższe porównanie jest po prostu bolesne. –

+0

Chociaż technicznie poprawne, ten wzór try/finally nie jest najlepszy. Użyj: X x = nowy X(); try {/ * work * /} finally {x.dysponować(); } – McDowell

2

Nie jestem tego świadomy. Możesz trochę symulować, próbując ... w końcu blokować, ale nadal nie jest tak samo.

-3

Nie, w Javie nie ma zastosowania, najbardziej podobną funkcjonalnością jest słowo kluczowe "import".

+0

Oryginalny plakat nie dotyczył uwzględnienia. Zobacz http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx – McDowell

+3

Poor @shifoz! Jesteście okrutni. Pytanie było całkowicie niejasne i mógł mieć na myśli ten http://msdn.microsoft.com/en-us/library/sf0df423 (VS.80) .aspx ... Shifoz, możesz odzyskać punkty, pytając o coś programiści tacy jak "jaki jest twój ulubiony kolor w RGB?" –

-2

Nie, nie ma.

Można

public void func(){ 

    { 
    ArrayList l = new ArrayList(); 
    } 
    System.out.println("Hello"); 

} 

To daje ograniczony zakres z wykorzystaniem klauzuli, ale nie ma żadnego interfejsu IDisposable zadzwonić kodu finalizacji. Możesz użyć try {} catch() {} Wreszcie {}, ale nie ma on cukru. Nawiasem mówiąc, używanie finalizatorów w Javie jest generalnie złym pomysłem.

1

Myślę, że można osiągnąć coś podobnego do bloku "używając", implementując anonimową klasę wewnętrzną. Podobnie jak Spring ma "Szablony Dao".

2

Najbliższe, które można uzyskać w Javie, to spróbuj/już. Ponadto Java nie zapewnia typu niejawnego jednorazowego użytku.

C# Zakresy zmienną na zewnątrz za pomocą bloku

public class X : System.IDisposable { 

    public void Dispose() { 
     System.Console.WriteLine("dispose"); 
    } 

    private static void Demo() { 
     X x = new X(); 
     using(x) { 
      int i = 1; 
      i = i/0; 
     } 
    } 

    public static void Main(System.String[] args) { 
     try { 
      Demo(); 
     } catch (System.DivideByZeroException) {} 
    } 

} 

Java: Zakresy zmiennej zewnątrz bloku

public class X { 

    public void dispose() { 
     System.out.println("dispose"); 
    } 

    private static void demo() { 
     X x = new X(); 
     try { 
      int i = 1/0; 
     } finally { 
      x.dispose(); 
     }   
    } 

    public static void main(String[] args) { 
     try { 
      demo(); 
     } catch(ArithmeticException e) {} 
    } 

} 

C# Zakresy zmienne wewnątrz bloku

public class X : System.IDisposable { 

    public void Dispose() { 
     System.Console.WriteLine("dispose"); 
    } 

    private static void Demo() { 
     using(X x = new X()) { 
      int i = 1; 
      i = i/0; 
     } 
    } 

    public static void Main(System.String[] args) { 
     try { 
      Demo(); 
     } catch (System.DivideByZeroException) {} 
    } 

} 

Java: scoping zmienną wewnątrz bloku

public class X { 

    public void dispose() { 
     System.out.println("dispose"); 
    } 

    private static void demo() { 
     { 
      X x = new X(); 
      try { 
       int i = 1/0; 
      } finally { 
       x.dispose(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      demo(); 
     } catch(ArithmeticException e) {} 
    } 

} 
0

Well, używając był cukier syntaktyczny tak więc towarzyszy Java, nie przejmuj się.

5

Najbliższym odpowiednikiem w języku jest użycie funkcji wypróbuj na końcu.

using (InputStream in as FileInputStream("myfile")) { 
    ... use in ... 
} 

staje

final InputStream in = FileInputStream("myfile"); 
try { 
    ... use in ... 
} finally { 
    in.close(); 
} 

Uwaga ogólna forma jest zawsze:

acquire; 
try { 
    use; 
} finally { 
    release; 
} 

Jeżeli nabycie jest w bloku try, można zwolnić w przypadku, gdy nabycie nie powiedzie się. W niektórych przypadkach możesz się włamać z niepotrzebnym kodem (zazwyczaj testując null w powyższym przykładzie), ale w przypadku, powiedzmy, ReentrantLock złe rzeczy się zdarzą.

Jeśli często robisz to samo, możesz użyć idiomu "wykonaj w pobliżu". Niestety składnia Javy jest pełna, więc jest dużo płyt z bolierami.

fileInput("myfile", new FileInput<Void>() { 
    public Void read(InputStream in) throws IOException { 
     ... use in ... 
     return null; 
    } 
}); 

gdzie

public static <T> T fileInput(FileInput<T> handler) throws IOException { 
    final InputStream in = FileInputStream("myfile"); 
    try { 
     handler.read(in); 
    } finally { 
     in.close(); 
    } 
} 

Bardziej skomplikowany przykład my, na przykład, owinąć wyjątki.

0

Jeśli otrzymamy zamknięcie BGGA w Javie, otworzyłoby się to również na podobne struktury w Javie. GPo wykorzystał ten przykład w swoich slajdów, na przykład:

withLock(lock) { //closure } 
0

Rzeczywista idiom używany przez większość programistów na pierwszym przykładzie jest to:

InputStream is1 = null; 
InputStream is2 = null; 
try{ 
    is1 = new FileInputStream("/tmp/bar"); 
    is2 = new FileInputStream("/tmp/foo"); 

    /* do stuff with is1 and is 2 */ 

} finally { 
    if (is1 != null) { 
     is1.close(); 
    } 
    if (is2 != null) { 
     is2.close(); 
    } 
} 

Jest mniej wcięć za pomocą tego idiomu, który staje jeszcze ważniejsze, gdy masz więcej niż 2 zasoby do porządkowania.

Ponadto można dodać klauzulę catch do struktury, która zajmie się nowym obiektem FileStream() wyrzucającym wyjątek, jeśli jest to potrzebne. W pierwszym przykładzie musiałbyś mieć inny zamykający blok try/catch, gdybyś chciał to zrobić.

+0

Ten kod nie zamyka wartości is2, jeśli wywołanie metody is1.close() zgłasza wyjątek. Zagnieżdżony kod podany w pytaniu jest preferowany. – cunkel

9

Tak, ponieważ Java 7 można przepisać:

InputStream is1 = new FileInputStream("/tmp/foo"); 
try{ 

    InputStream is2 = new FileInputStream("/tmp/bar"); 
    try{ 
     /* do stuff with is1 and is2 */ 

    } finally { 
     is2.close(); 
    } 
} finally { 
    is1.close(); 
} 

Jak

try(InputStream is1 = new FileInputStream("/tmp/foo"); 
    InputStream is2 = new FileInputStream("/tmp/bar")) { 
     /* do stuff with is1 and is2 */ 
} 

Te przekazywane jako parametry do instrukcji try powinny wdrożyć java.lang.AutoCloseable .Have spojrzeć na official docs obiekty.

Dla starszych wersji Java Checkout this answer i this answer.

Powiązane problemy