'Java' komutu Java programlarını derliyor mu?


147

İnternetteki çoğu web sitesi şunu söylüyor:

" javacbir .javadosyayı derlemek için komutu kullanın . Ardından javakomutu kullanarak çalıştırın "

Ama bugün bir java programını onsuz çalıştırmayı denedim javacve garip bir sonuç aldım.

İşte adlı bir dosyanın içeriği hello.java:

public class Myclass {
 public static void main(String[] args){
    System.out.println("hello world");
  }
}

Sonra koştum:

$ javac hello.java

Bu bana şu hatayı veriyor:

hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java
public class Myclass {
       ^
1 error

Ama javackomut olmadan çalıştırdığımda herhangi bir hata olmadan yürütüldü.

$ java hello.java
hello world

Does javakomut ayrıca bir program derlemek? Cevabınız evet ise, neden javackomuta ihtiyacımız var ?

Java'mın sürümü:

openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)

11
Hangi sürümü kullanıyorsunuz? Bence Java Konsolu'nu Java 9'da tanıttılar ve deneyimlediğiniz şey bu olabilir.
Matthieu

6
Sınıf adını dosya adıyla eşleştirmeniz gerekir - bu Java standardıdır. Sadece dosya adını olarak değiştirin Myclass.javave ardından komut satırından bu şekilde derleyin javac Myclass.javave ardından bu şekilde çalıştırın java Myclass.
2019

6
evet, javackaynak kodunu dağıtmak istemiyorsanız hala derlemek için kullanılan ya da daha fazlası tek bir dosyadan daha var ( dokümantasyon ait java: kaynak-dosya seçeneği için sadece tek bir kaynak-dosya programı başlatmak için kullanılır.)
user85421

@Matthieu "java sürümü" çıktısı şöyledir: openjdk sürümü "12.0.2" 2019-07-16 OpenJDK Çalışma Zamanı Ortamı (derleme 12.0.2 + 10) OpenJDK 64-Bit Sunucu VM (derleme 12.0.2 + 10, karışık mod)
milad

1
@Milad - Bu ne olur - javacJava kaynağını JVM'ye özel yorumlanan bayt kodu olarak derler ve javakomut onu JVM'nin ClassLoader'ına yükler.
2019

Yanıtlar:


190

Java 11'den önce, kodunuzu çalıştırmak için önce onu derlemelisiniz, sonra çalıştırabilirsiniz. İşte bir örnek:

javac test.java
java test

Java 11'den beri javac+ javayapabilir veya javakodunuzu derlemek ve otomatik olarak çalıştırmak için kendi başına çalıştırabilirsiniz. Hiçbir .classdosyanın oluşturulmayacağını unutmayın. İşte bir örnek:

java test.java

Eğer kaçarsan java -help, çeşitli evcil kullanımlarını göreceksiniz. İşte benim makinemde göründüğü gibi. Sonuncusu, karşılaştığınız şeydir: java [options] <sourcefile> [args]"tek bir kaynak dosya programını çalıştıracak".

$ java -help
Usage: java [options] <mainclass> [args...]
           (to execute a class)
   or  java [options] -jar <jarfile> [args...]
           (to execute a jar file)
   or  java [options] -m <module>[/<mainclass>] [args...]
       java [options] --module <module>[/<mainclass>] [args...]
           (to execute the main class in a module)
   or  java [options] <sourcefile> [args]
           (to execute a single source-file program)

GÜNCELLEME:

@ BillK tarafından belirtildiği gibi, OP ayrıca şunları sordu:

javac komutuna neden ihtiyacımız var?

İhtiyaç duymamızın nedeni , kodun bugün olduğu gibi oluşturulabilmesi, test edilebilmesi, dağıtılabilmesi, çalıştırılabilmesi, paylaşılabilmesi vb. İçin dosyalar javacoluşturmaktır .class. JEP 330'un motivasyonu, mevcut diğer kullanımları değiştirmeden "Java öğrenmenin erken aşamalarında ve küçük yardımcı programlar yazarken" kolaylaştırmaktı .


49
Java 11'de tanıtıldı: Yenilikler ve / ve JEP 330: Tek
Dosyalı

Ek ayrıntılar için @CarlosHeuberger'e teşekkürler.
kaan

7
Java 8 var @Spikatrix (Onlar düştü 1.de 1.8yeni sürümlerde)
Muru

1
Neden hala javac'a ihtiyacımız olduğu sorusuna cevap vermediniz - sanırım java yalnızca sağladığınız tek dosya ve önceden derlenmiş dosyalar üzerinde çalışır. Kullanmak istediğiniz diğer tüm dosyaları aradığınız dosyadan derlemeniz gerektiğine inanıyorum.
Bill K

2
Bu yanıt, bu yeni yöntemin neden bildirildiği gibi dosya adı ve sınıf adı hatasıyla sonuçlanmadığını ele almıyor javac.
sebrockm

52

Java 11 çalıştırıyorsanız , tek kaynaklı dosyanın yürütülmesine izin veren yeni bir özellik vardır. Tek kaynak derleyici, dosya adına karşı sınıf adı açısından daha belirsizdir, bu nedenle çalıştırabilirsiniz ancak başarılı bir şekilde derleyemezsiniz.

Java'nın önceki bir sürümündeyseniz, mevcut hello.java dosyanız derleme hataları nedeniyle, özellikle sınıf adı etrafında derlenmez. Yani java hello.java'yı çağırmanın kodunuzu derlemesinin hiçbir yolu yoktur, çünkü o derlemez.

Java komutunu çalıştırırken büyük olasılıkla önceden derlenmiş bir kod çalıştırıyormuşsunuz gibi görünüyor.


teşekkür ederim, java sürümü: openjdk sürümü "12.0.2" 2019-07-16 OpenJDK Çalışma Zamanı Ortamı (derleme 12.0.2 + 10) OpenJDK 64-Bit Sunucu VM (derleme 12.0.2 + 10, karma mod)
milad

5
Tek Dosyalı Kaynak Kodu Programlarını Başlatmak için Kaynak-Dosya Modunu Kullanmayı kontrol edin : "Derleyici, JLS 7.6'nın sonunda tanımlanan isteğe bağlı bir pakette bir türün adı olan tür adından ve ardından .java uzantısından oluşur. "
user85421

2
Java komut dosyası oluşturma API'si ve Java Tek Dosyalı Kaynak Kodlu Program Başlatma ( JEP 330 ), tamamen ayrı ve tamamen ilgisiz iki şeydir.
David Conrad

@DavidConrad, laf kalabalığı buna göre güncellendi. Teşekkürler.
Evan

@TJCrowder girdisini takdir edin. Ama olduğu gibi yazmak istediğimden oldukça eminim. Ayrıca, bağlantılarınızdaki ikinci tanım: Karışık, çok çeşitli farklı şeyler içeren anlamına gelir.
Evan

6

Bu hatanın neden verildiğini yanıtlamak için, dosyanın sınıf adı dosyanın basename.

Bu kodun geleneksel için çalışmasını sağlamak için iki seçeneğiniz vardır javac; javasıra:

  1. Sınıfı public class Helloveya olarak yeniden adlandırın

  2. Rename hello.javaiçin myclass.java.

javaJava 11 tercüman bu gereksinimi empoze etmez. İçerdiği mainsınıf, dosyadaki birinci sınıf olduğu sürece herhangi bir ada sahip olabilir. Bu, temel olarak yeni başlayanlar için öğrenme sürecini kolaylaştırmak ve shebang ( ref. ) İle "java komut dosyası oluşturmaya" izin vermek için tasarlanmıştı .


5

Evet, ama muhtemelen kastettiğin şekilde değil.

Bir javac.java dosyasını bir .class dosyasına derlemek için komutu kullandığınızda, çıktıya bayt kodu adı verilir. Bytecode, Java Virtual Machine spesifikasyonuna dayalı teorik bir CPU için bir makine kodudur (yerel talimatlar).

Bu sanal CPU spesifikasyonu, spesifikasyonun yazıldığı sırada yaygın olan ortalama CPU tipleridir. Bu nedenle, birçok farklı CPU türüne yakın olması, aynı Java .class dosyalarını birden çok CPU türünde çalıştırmayı kolaylaştırır.

Java ilk başlatıldığında, javakomut .class dosyasını okur ve bayt kodu talimatlarını birer birer yorumlar ve ardından bunları gerçekte hangi CPU üzerinde çalıştığı için eşdeğer yerel talimatla eşler. Bu işe yaradı ama özellikle hızlı değildi. Bu Just in Time (JIT) derlemesini geliştirmek için Java Runtime'a eklendi.

JIT ile javakomut bayt kodunu alır ve üzerinde çalıştığı CPU için yerel talimatlara yeniden derler. Modern Java çalışma zamanları, JIT arka planda derlenirken bayt kodunu yorumlamaya başlar ve hazır olduğunda derlenmiş yerel talimatlara geçer ve ayrıca çalışan uygulamanın profilini çıkarır ve ardından mümkün olan en iyi performansı elde etmek için bayt kodunu farklı optimizasyonlarla yeniden derler.

DÜZENLEME (olumsuz seçmenleri yatıştırmak için):

Yani sizin özel durumunuzda (v11'den daha yeni bir JRE çalıştırdığınız için) kod (en az) iki kez derlenir

  1. Bayt koduna tek bir .java dosyası olarak
  2. Bayt kodunu yorumlarken JIT derleyicisi aracılığıyla (helloWorld için aslında derlenmiş yerel kodlardan herhangi birini çalıştırmak için zaman bulamayabilir)

7
Bu soruya cevap vermiyor.
David Conrad

2
@DavidConrad Ama öyle! "'Java' komutu Java programlarını derliyor mu?" hardlib'in burada verdiği nedenlerden ötürü yankılanan bir "evet" dir: bayt kodunu tam zamanında yerel talimatlara derler (önemsiz olmayan programlar için, standart ayarlarla).
Peter - Monica'yı Yeniden

Derleme artık zorunlu mu? Tarihsel olarak Java bayt kodu yorumlanabilirdi; JIT derlemesi isteğe bağlıydı.
MSalters

JIT, mixed-modesürüm çıktısında gösterildiği gibi bu günlerde varsayılan olarak (çok uzun bir süredir)
açıktır
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.