Sonunda java'da çalışmayabilecek herhangi bir koşul var mı? Teşekkürler.
Sonunda java'da çalışmayabilecek herhangi bir koşul var mı? Teşekkürler.
Yanıtlar:
dan Güneş Rehberler
Not: Try veya catch kodu yürütülürken JVM'den çıkılırsa, final bloğu çalışmayabilir. Benzer şekilde, dene ya da yakala kodunu yürüten iş parçacığı kesintiye uğrarsa ya da öldürülürse, uygulama bir bütün olarak devam etse bile final bloğu yürütülemeyebilir.
Nihayet bloğunun uygulanmayacağı başka yollar bilmiyorum ...
System.exit , Sanal Makineyi kapatır.
Şu anda çalışan Java Virtual Machine'i sonlandırır. Argüman bir durum kodu görevi görür; kural olarak, sıfırdan farklı bir durum kodu anormal sonlandırmayı gösterir.
Bu yöntem
exit
, sınıftaki yöntemi çağırırRuntime
. Bu yöntem asla normal şekilde geri dönmez.
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
"güle güle" yukarıdaki kodda yazdırılmaz.
Sadece başkalarının söylediklerini genişletmek için, JVM'nin çıkması gibi bir şeye neden olmayan herhangi bir şey, nihayet engellenmesine neden olacaktır. Yani aşağıdaki yöntem:
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
garip bir şekilde hem derleyecek hem de 1 döndürecektir.
System.exit ile ilgili olarak, bir nihayet bloğunun yürütülemeyebileceği belirli yıkıcı hata türleri de vardır. JVM'nin belleği tamamen tükenirse, yakalanmadan çıkabilir veya sonunda gerçekleşebilir.
Özellikle aptalca kullanmaya çalıştığımız bir projeyi hatırlıyorum
catch (OutOfMemoryError oome) {
// do stuff
}
Bu işe yaramadı çünkü JVM'de catch bloğunu yürütmek için bellek kalmamıştı.
try { for (;;); } finally { System.err.println("?"); }
Bu durumda, nihayet çalıştırılmayacaktır (kullanımdan kaldırılan Thread.stop
çağrılmadıkça veya bir eşdeğeri, örneğin bir araçlar arayüzü aracılığıyla).
throw
, finally
blok beklendiği gibi çalışacaktır. try { throw new ThreadDeath(); } finally { System.err.println("?"); }
Sun öğreticisi, bu ileti dizisinde yanlış bir şekilde alıntılanmıştır.
Not: deneyin veya catch kod yürütülürken JVM çıkışlar, daha sonra nihayet blok halinde olacaktır yürütmüyor. Deneyin veya catch kod yürütme iş parçacığı kesintiye veya öldürülürse Aynı şekilde, nihayet blok olacak bir bütün olarak uygulama devam etse bile yürütmüyor.
Nihayet engellenmesi için güneş eğitimine yakından bakarsanız, "çalıştırılmayacak" ancak "çalıştırılamayabilir" demiyor. İşte doğru açıklama
Not: deneyin veya catch kod yürütülürken JVM çıkışlar, daha sonra nihayet blok halinde olabilir yürütmüyor. Deneyin veya catch kod yürütme iş parçacığı kesintiye veya öldürülürse Aynı şekilde, nihayet blok olabilir bir bütün olarak uygulama devam etse bile yürütmüyor.
Bu davranışın görünürdeki nedeni, system.exit () çağrısının, jvm'yi kapatmak için zaman alabilen bir çalışma zamanı sistem iş parçacığında işlenmesi, bu arada iş parçacığı zamanlayıcının en sonunda yürütmeyi isteyebilmesidir. Yani nihayet her zaman çalıştırmak için tasarlanmıştır, ancak jvm'yi kapatıyorsanız, jvm nihayet yürütülmeden önce kapanabilir.
Ayrıca try
bloğun içinde bir kilitlenme / canlanma meydana gelirse .
İşte bunu gösteren kod:
public class DeadLocker {
private static class SampleRunnable implements Runnable {
private String threadId;
private Object lock1;
private Object lock2;
public SampleRunnable(String threadId, Object lock1, Object lock2) {
super();
this.threadId = threadId;
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
synchronized (lock1) {
System.out.println(threadId + " inside lock1");
Thread.sleep(1000);
synchronized (lock2) {
System.out.println(threadId + " inside lock2");
}
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
public static void main(String[] args) throws Exception {
Object ob1 = new Object();
Object ob2 = new Object();
Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
t1.start();
t2.start();
}
}
Bu kod aşağıdaki çıktıyı üretir:
t1 inside lock1
t2 inside lock1
ve "nihayet" asla yazdırılmaz
Try veya catch kodu çalıştırılırken JVM çıkarsa, final bloğu çalışmayabilir. ( kaynak )
Normal Kapatma - bu, arka plan programı olmayan son iş parçacığı çıktığında VEYA Runtime.exit () ( kaynak ) olduğunda gerçekleşir
Bir evre çıkış yaptığında, JVM çalışan evrelerin bir envanterini gerçekleştirir ve geriye kalan tek evreler arka plan programı evreleri ise, düzenli bir kapatma başlatır. JVM durduğunda, kalan tüm arka plan programı evreleri terk edilir ve sonunda bloklar çalıştırılmaz, yığınlar çözülmez, JVM'den çıkılır. Daemon iş parçacıkları idareli kullanılmalıdır, çok az işleme faaliyeti herhangi bir zamanda temizlik olmadan güvenle terk edilebilir. Özellikle, her tür G / Ç gerçekleştirebilecek görevler için daemon evrelerini kullanmak tehlikelidir. Daemon iş parçacıkları, bir bellek içi önbellekten süresi dolan girdileri düzenli olarak kaldıran bir arka plan iş parçacığı gibi "temizlik" görevleri için en iyi şekilde kaydedilir. ( kaynak )
Son arka plan programı olmayan iş parçacığı örneği:
public class TestDaemon {
private static Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
Çıktı:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
Aşağıdaki durumlarda, nihayet bloğu yürütülmeyecektir: -
System.exit(0)
çağrılır try
. try
bloğu Nihayet bloğunun uygulanmayacağı başka sınır durumlar da olabilir.
Sonunda blok kodu yürütmeyi durdurmanın iki yolu vardır:
1. System.exit () kullanın;
2. Bir şekilde yürütme kontrolü bloğu denemek için ulaşmazsa.
Görmek:
public class Main
{
public static void main (String[]args)
{
if(true){
System.out.println("will exceute");
}else{
try{
System.out.println("result = "+5/0);
}catch(ArithmeticException e){
System.out.println("will not exceute");
}finally{
System.out.println("will not exceute");
}
}
}
}
Özellikle oyun çerçevesiyle ilgili olarak yürütülmeyen son blokun çok özel bir durumuna rastladım.
Bu denetleyici eylem kodundaki en sonunda bloğunun yalnızca bir İstisnadan sonra çağrıldığını, ancak çağrı gerçekten başarılı olduğunda asla çağrılmadığını görünce şaşırdım.
try {
InputStream is = getInputStreamMethod();
renderBinary(is, "out.zip");
catch (Exception e) {
e.printStackTrace();
} finally {
cleanUp();
}
Belki iş parçacığı sonlandırılır veya renderBinary () çağrıldığında başka bir şey olabilir. Aynı şeyin diğer render () çağrıları için de gerçekleştiğinden şüphelenirdim, ancak doğrulamadım.
RenderBinary () 'yi try / catch sonrasına taşıyarak problemi çözdüm. Daha fazla araştırma, oynatmanın, bir denetleyici eylemi yürütüldükten sonra yürütülen bir yöntem oluşturmak için bir @Finally ek açıklaması sağladığını ortaya çıkardı. Buradaki uyarı, bunun denetleyicideki HERHANGİ bir eylemin gerçekleştirilmesinden sonra çağrılacağıdır, bu nedenle her zaman iyi bir seçim olmayabilir.
//If ArithmeticException Occur Inner finally would not be executed
class Temp
{
public static void main(String[] s)
{
try
{
int x = 10/s.length;
System.out.println(x);
try
{
int z[] = new int[s.length];
z[10] = 1000;
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
}
finally
{
System.out.println("Inner finally");
}
}
catch(ArithmeticException e)
{
System.out.println(e);
}
finally
{
System.out.println("Outer Finally");
}
System.out.println("Remaining Code");
}
}