Main geçerli bir Java tanımlayıcısı mı?


288

Çocuklarımdan biri lisede Java kullanıyor ve bunu testlerinden birinde yaptı:

Aşağıdakilerden hangisi Java'da geçerli bir tanımlayıcıdır?

a. 123java
b. main
c. java1234
d. {abce
e. )whoot

Cevap verdi b ve yanlış anladı.

Söz bakıp savundu main olan geçerli bir tanımlayıcı ve doğru olması gerektiğini söyledi.

Tanımlayıcılar için Java spesifikasyonlarına bir göz attık ve bu noktayı pekiştirdi. Ayrıca bir değişkenin mainyanı sıra bir metod adı verilen örnek bir program da yazdık . Java dokümantasyon referansını içeren bir çürütme yarattı, test programı ve öğretmen bunu görmezden geldi ve cevabın hala yanlış olduğunu söylüyor.

maingeçerli bir tanımlayıcı?


12
Bir öğretmeni görmek o kadar güvensiz ki, yeni bir şey öğrenmekten ve bir hatayı kabul etmekten korkuyor.
Ryan Lundy

tahminimce o. ama gerçekten bir değişken / yöntem adı olarak kullanmamalısınız (buna rağmen bariz durum), eğer öğretmen ev noktasını düşünmeye çalışıyorsa - özellikle bu durumda - yöntem isimleri onun amacı.
bharal

3
Bu soru, oğlunuzun öğretmeninin işini doğru bir şekilde yapıp yapmadığını gerçekten soruyor mu? İki geçerli Java tanımlayıcısı görüyorum. Yani cevap 'b' VE 'c'. Yani öğretmen doğrudur. Yoksa bir şey mi kaçırıyorum? Bu nasıl bir SO sorusu olabilir? Topluluğun bir parçası bile olmayan
birisini yargılamak

1
Bu, java hakkında değil öğretmenler hakkında bir soru.
ACV

1
"Kendi hile sorunuz tarafından kandırılan" vakalardan bir diğeri; öğretmenler böyle bir sınav sorusu yazmaya çalışmadan önce en azından dil spesifikasyonlarına bir göz atmalıdır.
jrh

Yanıtlar:


253
public class J {
    public static void main(String[] args)
    {
        String main = "The character sequence \"main\" is an identifier, not a keyword or reserved word.";
        System.out.println(main);
    }
}

Bu derlenir ve yürütüldüğünde bu çıktıyı yayar:

The character sequence "main" is an identifier, not a keyword or reserved word.

Karakter sırası main, bir anahtar sözcük veya ayrılmış bir sözcük değil, bir tanımlayıcıdır.

JLS ilgili bölüm 3.8 olduğunu :

Bir tanımlayıcı , birincisi bir Java harfi olması gereken sınırsız uzunlukta Java harfleri ve Java rakamları dizisidir .

Tanımlayıcı:

    IdentifierChars ancak bir Anahtar Kelime veya BooleanLiteral veya NullLiteral değil

IdentifierChars:

    JavaLetter {JavaLetterOrDigit}

JavaLetter:

    "Java harfi" olan herhangi bir Unicode karakteri

JavaLetterOrDigit:

    "Java harfi veya rakamı" olan herhangi bir Unicode karakteri

Karakter sırası mainyukarıdaki açıklamaya uyar ve Bölüm 3.9'daki anahtar kelime listesinde değildir .

(Karakter sırası java1234da aynı nedenlerle bir tanımlayıcıdır.)


25
@Clockwork Soru sadece bir seçimin doğru olabileceği şekilde ifade edildi. Bununla birlikte, b ve c seçeneklerinin her ikisi de , zımni seçimle tutarsız olarak sorunun durumunu tatmin etmiştir. Bu, OP'nin çocuğunu, öğretmenin doğru olduğunu düşündüğü tek cevapın hangi doğru cevap olduğunu seçmeye bıraktı.
rgettman

@rgettman " Aşağıdakilerden hangisini ... " birden fazla seçeneğe izin vererek, " b ve c " nin geçerli bir yanıt olacağını okudum .
TripeHound

6
@TripeHound "geçerli bir tanımlayıcıdır" tekildir ve tam olarak 1 cevap gerektirir. "Geçerli tanımlayıcılar" ile karşılaştırın
411

2
Sınıfı da yapmış olabilirsiniz main;)
Peter Lawrey

97

main geçerli bir java tanımlayıcısı ve öğretmen yanlış.

İlgili belgeler Java Dil Spesifikasyonundadır, tam burada:

Bölüm 3. "Sözcüksel Yapı", bölüm 3.8. "Tanımlayıcılar":

https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8

Diyor ki:

Bir tanımlayıcı, bir Java harfi olması gereken sınırsız uzunlukta bir Java harfleri ve Java rakamları dizisidir ... Bir tanımlayıcı, bir anahtar sözcükle (§3.9), boole değişmez ( §3.10.3) veya boş değişmez değeri (§3.10.7) veya derleme zamanı hatası oluşur.

Bu, geçerli bir tanımlayıcı olduğunu şu şekilde kanıtlayabileceğiniz anlamına gelir:

  • java anahtar kelimeler listesinde (ipucu: orada bulamazsınız!) veya sadece
  • bir tanımlayıcı olarak kullanmak ve derleme zamanı hatası oluşmadığını gözlemlemek.

1
Daha açık bir şekilde alıntı yapabilir ve heceleyebilir misiniz?
zero298

36
hayır, çünkü bu bütün bir bölüm. Öğretmen bu bölümün 'ana' için bir tür istisna yaptığını düşünüyorsa, nerede söylediklerini göstermesi gereken öğretmendir.
Mike Nakis

76

Diğer cevapların belirttiği gibi

mainGeçerli bir Java tanımlayıcı olan , hem de java1234.

Sanırım kafa karıştırıcı, main(String[])yöntemin genellikle JVM 1 tarafından giriş noktası olarak kullanılması gerçeğinden kaynaklanmaktadır . Ancak bu, belirtecin mainkendisinin tanımlayıcı 2 olarak kullanılamayacağı anlamına gelmez .

Spesifikasyonlar böyle söylüyor ve aşağıdaki beyanlar da geçerlidir:

  • Bir alan:

    private int main;
  • Yerel bir değişken:

    String main = "";
  • Bir metod:

    private void main() { ... }
  • Bir sınıf (küçük harfle başlayan bir sınıf adı önerilmez):

    public class main { ... }
  • Bir paket:

    package main;

1: Yorumlarda belirtildiği gibi, JVM spesifikasyonunun kendisi giriş noktası olarak belirli bir yöntemi zorunlu kılmaz, ancak yaygın olarak kullanılan javaaraç genellikle giriş noktası olarak böyle bir yöntem kullanır.
2: Genelde farklı bir yöntem oluşturmaktan kaçınırım main(String[]).


22
"Sanırım kafa karıştırıcı, ana (String []) yönteminin JVM için giriş noktası olarak kullanılmasından kaynaklanıyor." mainJVM için giriş noktası değil. javaAracın uygulamaları çalıştırmak için kullandığı giriş noktasıdır . Diğer araçlar (örneğin sunucu uygulaması kapları) diğer giriş noktalarını kullanır.
TJ Crowder

27
ki bu daha da ironiktir, çünkü "giriş noktası bağlamında" ana ZATEN geçerli bir tanımlayıcıdır. Bu yüzden buna karşı koyabileceğiniz dava bile OP'nin doğru olduğunu kanıtlıyor
Hobbamok

@TJCrowder Teşekkürler, cevaba ekledim.
MC İmparatoru

1
@Hobbamok Muhtemelen bir okulda öğretmek ve pratik değil açıklıyor temel Java kavramlar, yaklaşık karıştı görünmek aklın gelir Cevap
Rath

4
javaAracı gerektirmez main(String[])ana sınıfı genişletir eğer yöntemini javafx.application.Application .
VGR

65

Bu Java 1.8 iyi derler ...

public class main {

    public String main = "main"; 

    public void main(String main) {
        System.out.println("This object is an instance of the class " + this.getClass().getCanonicalName());
        System.out.println("The value of the argument \"main\" for this call to the method \"main(String main)\" is " + main);
        System.out.println("The value of the field \"main\" is " + this.main);
    }

    public static void main(String[] args) {
        main main = new main();
        main.main(main.main + main.main);
    }
}

... ve yürütüldüğünde çıktı üretir:

This object is an instance of the class main
The value of the argument "main" for this call to the method "main(String main)" is mainmain
The value of the field "main" is main

5
static mainFarklı parametrelerle başka bir yöntem eklemek mümkün müdür ?
jpmc26

6
@ jpmc26 Deneyin ve bize nasıl gittiğini anlatın. :)
MichaelK

1
Eh işte şebeke bir sürü
MC İmparatoru

4
@MCEmperor Evet, bu cevabım için ana argümanım. ;)
MichaelK

3
Eklemeyi unuttun package main;!
Solomon Ucko

45

Olabildiğim her şeyi attım ve işe yarıyor gibi görünüyor. Main'nin geçerli bir tanımlayıcı olduğunu söyleyebilirim.

package main;

public class main {

    static main main;
    String Main;

    main(String main) {
        Main = main;
    }

    main(main main) {
        System.out.println(main.Main);
    }

    main main(main main) {
        return new main(main);
    }

    public static void main(main...Main) {
        main:
        for (main main : Main) {
            main = (main instanceof Main) ? new main(main): main.main(main);
            break main;
        }
    }

    public static void main(String[] args) {
        main = new main("main");
        main.main(main, main);
        main = main.new Main(main) {
            main main(main main) {
                return ((Main)main).main();
            }
        };
        main.main(main);
        main.main(main,main);
    }

    abstract class Main extends main {
        Main(main main) {
            super("main");
        }

        main main() {
            main.Main = "Main";
            return main;
        }
    }
}

2
Bunu sevdim. Bir 'grep -o main main.java | wc -l '
Gary Bak

3
Bu kod bana "ook" programlama dilini hatırlatıyor ^ ^ Bu koddaki hemen hemen her kelime "ana" ...
Florian Bach

public static void main(main...Main)( bir alanı eksik ) çalışamaz, değil mi?
GeroldBroser Monica geri getiriyor

3
Bunu ana hatlarıyla anlatmış gibi hissediyorum.
Ross Presser

1
@GeroldBroser Bu daha temiz, ancak kesinlikle gerekli değildir: jetonlar arasındaki boşluklar birçok durumda isteğe bağlıdır, yalnızca sonraki iki jetonun birleştirilmesi de geçerli olduğunda gereklidir.
MC İmparatoru

44

main"Ana" yöntemi bildirmek için tanımlayıcı olarak kullanılırken tanımlayıcı olarak nasıl kullanılamaz?

Böyle klasik bir deyim için:

public class Foo{
   public static void main(String[] args){
   }
}

main bir anahtar kelime değildir ve muhtemelen açık retro uyumluluk nedenleriyle Java'da hiçbir zaman bir anahtar kelime olmaz.


Soru hakkında, mainiyi bir tanımlayıcı mı?

Birincisi: derleyici için geçerli olması mutlaka iyi anlamına gelmez.
Örneğin,java1234 önerilen seçenek de geçerli bir tanımlayıcıdır, ancak bundan kaçınılmalıdır.

main çok özel ve önemli bir anlamı vardır: tarafından yürütülen sınıfların ve kavanozların giriş noktası yöntemi olarak kullanılır. java komut satırı .
Kullanarak maintarafından kullanılacak kriterleri doldurmayan bir yöntem adı için javakomut satırında değişken adı olarak kullanan veya sınıf adı anlamlı olamaz çıkarırken sadece yanıltıcı olacaktır.
Örneğin, bir uygulamanın giriş noktasını temsil eden sınıfı uygulamanın Mainsınıfı olarak tanımlamak kabul edilebilir ve bu nedenle de değişken adı olarak kullanmak:

public class Main {

  public static void main(String args[]){
     Main main = new Main();
     // ...
  }      

}

Genel olarak, Java'da, birden çok karakter veya "kelime" derleyici için geçerli tanımlayıcılar olarak kabul edilir, ancak istemci kodunda kullanılması kesinlikle önerilmez (ancak oluşturulan kod bunu yapabilir: örneğin iç içe sınıflar) okunabilir ve / ya da gerçekten yanıltıcı.

Örneğin bu derleyici için geçerli olabilir:

public class Object { // 1
    public void foo() {
       ...
    }
}

public class BadChosenIdentifier {

    public static void main() { // 2
        new BadChosenIdentifier().toString(new Object());  
    }

    public void toString(Object java1234) { // 3, 4
        String _result$ = java1234 + " -> to avoid"; // 4
        System.out.println(_result$);
    }    
}

Ama istemiyoruz:

  • isim Objectbu tanımlandığı gibidir sınıfımızı java.lang(1).
  • komut satırı (2) main()tarafından kullanılacak ölçütleri karşılamıyorsa yöntemi adlandırmak için java.
  • Object.toString()(3) yöntemini aşırı yüklemek için .
  • Bizim değişkenleri isim _, $veya paylaşılan adlandırma kurallarına (4) aykırı herhangi şaşırtıcı / unmeaningful karakterleri.

7
Sadece not etmek gerekirse, mainsadece uygun bir imzayla (veya herhangi bir şekilde) statik bir yöntem için bir ad olarak kullanılabilen bir anahtar kelime olabilir. Süper sınıf çağrılarının superbir tanımlayıcı gibi görünmesini sağlayacak şekilde kullanıldığını unutmayın : super(foo);ve super.fooancak superbir anahtar kelime IS (ve jenerikler eklenmeden önce, bunu kullanmanın tek yolu (hatırlayabildiğim)).
jaxad0127

@ jaxad0127 İlginç bir nokta ama tamamen katılmıyorum. Aslında öyle değil ve gelecekte hala uyumluluk nedenlerinden ötürü olmayabilir. mainJava'nın yeni bir sürümünde anahtar kelime olarak tanımladıysanız , main yöntemi yöntem adı (veya herhangi bir üye adı) olarak kullanan herhangi bir kodun artık derlenmeyeceği anlamına gelir. superJeneriklerin kullanımının mevcut kodda herhangi bir yan etkisi yoktur, çünkü jenerikler şu anda mevcut değildir.
davidxxx

2
Sadece bir anahtar kelime olarak YAPILABİLDİ demek istedim. Bir tanımlayıcıya benzediği için olması gerektiği anlamına gelmez.
jaxad0127

2
Bunun mainhala daha iyi bir tanımlayıcı olduğunu iddia ediyorum java1234. "Normal" bir yöntem için kullanmak yanıltıcı olurdu, ama mainaslında benim yöntemde bir şey ana eğer, bir değişken adlandırma sorunum olmazdı . java1234sadece korkunç, isimler açıklayıcı olmalı ...
AJPerez

1
"Soru hakkında, ana iyi bir tanımlayıcı mı?" Değişir. Muhtemelen mainbaktığım fonksiyon su ana verileri ile bir şey yaptıysa, adlandırılmış bir değişkene göz yummuyordum . Ben eğer kusmak istiyorum hiç gördüğümüz java1234üretim kodunda (ve öneki ile değil 1233 diğer değişkenler vardı dua java).
jpmc26

40

Geçerli bir tanımlayıcı mı? Evet.

İyi bir tanımlayıcı mı? JVM lansmanında başlayan yöntemden başka bir şey için kullanmıyorsanız değil.

Başka bir geçerli tanımlayıcı listeleniyor mu? Evet.

Test talimatları en iyi cevabı seçtiğini söyledi mi?


7
Kabul edildi - bunun gibi çoklu seçim, çoklu olduğunda 'en iyi' doğru cevabı seçmektir. Ancak, bu çok iyi bir soru değildir ve bence öğretmenle bunun hakkında konuşmak doğru bir şeydir.
Gölge

19
@Shadow Bu bir programlama dersidir. Resmi matematiksel dilbilgisi ile belirtilen bir konuda soru belirsizliği dayanılmazdır. Bu standarda (" geçerli " nin ima ettiği ) kesinlikle değinerek , her iki cevap da eşit derecede doğrudur. mainTolere edilebilecek bir tanımlayıcı olan çok daha fazla vakayı hayal edebileceğimden çok daha fazla hayal edebiliyorum java1234. Örneğin, su temini verileriyle (su şebekesi) çalışan bir kod tabanını düşünün.
jpmc26

5
Öte yandan, java1234 tanımlayıcı olarak cennete yükselir.
Joshua

4
“en iyi cevabı seç” demek, “öğretmenin ne hakkında konuştuklarını bilmediğini anlayın ve düşündükleri kötü cevabı tahmin edin” anlamına gelmez. main sadece geçerli bir tanımlayıcı değildir, her Java uygulamasının bir ana yöntemi olduğundan ve yöntemler tanımlayıcılarla adlandırıldığından çok önemli bir tanımlayıcıdır.
fluffysheap

2
Bu cevabı çok iyi düşünmüş buluyorum ve keşke birden fazla kez oy verebilsem. Her ne pahasına olursa olsun taraf tutmaya çalışıyorsunuz ve daha geniş resmi düşünmüyorsunuz. maindüz Java uygulamasının dar etki alanının dışında herhangi bir yerde mükemmel bir tanımlayıcıdır. Sınıftaki bir set menüsünü temsil eden bir alanın adı olabilir. Veya <main>HTML oluşturucudaki bir belgenin bir bölümü. java1234Öte yandan, tanımlayıcıların elde ettiği kadar korkunç.
toniedzwiedz


29
public class Main {
    private static String main;
    public static void main(String[] main) {
        Main.main = main[0];
        new Main().main(Main.main);
    }
    private void main(String main) {
        System.out.println(main);
    }
}

7

Yani öğretmen ya varsayarak küçük bir hata yaptı ana geçerli bir tanımlayıcı değildir ya da sadece soru yanlış phrasing. Muhtemelen "iyi bir tanımlayıcı" demek istemişti.
Ancak oğullarınızın argümanlarını görmezden gelmek ve böylece ilgili literatürü (Java belirtimi) kontrol etmek ve bir deney yapmak (örnek bir program yazmak) konusundaki bilimsel yaklaşımını caydırmak, bir öğretmenin yapması gerekenin tam tersidir .


1
Diğer cevaplarda belirtildiği gibi, maingenellikle daha iyi bir "iyi" tanımlayıcıdır java1234. Yani orada bile, öğretmen yanlış. ;)
jpmc26

5

Hem mainve hem java123de geçerli tanımlayıcılardır, ana ayrılmış bir anahtar kelime değildir, bu yüzden kullanımı mükemmel kabul edilebilir, test ilerledikçe en azından bir veya yarım puan almış olmalısınız.


5
  1. Tek kelime olmalı. Yani boşluklara izin verilmiyor.

    Örnek: mangoprice geçerli, ancak mango fiyatı geçerli değil.

  2. Bir harf (alfabe) veya alt çizgi veya $ sembolü ile başlamalıdır.

    Örnek: price, _price ve $ price geçerli tanımlayıcılardır.

  3. Anahtar kelime derleyiciye özel bir anlam taşıdığından, Java anahtar sözcüğü olmamalıdır.

    Örnek: sınıf veya boşluk vb.

  4. Bir rakamla başlamamalı ancak rakam ortada veya sonunda olabilir.

    Örnek: 5mangoescost geçerli değildir ve mango5cost ve mangocost5 geçerlidir.

  5. Java'da bir tanımlayıcının uzunluğu 65.535 karakter olabilir ve tümü önemlidir. Tanımlayıcılar büyük / küçük harfe duyarlıdır. Yani hem mango hem de Mango farklı muamele görür. Tüm büyük harfleri veya küçük harfleri veya bir karışımı içerebilir.

KİMLİK : sınıf adları, yöntem adları, değişken adlarıdır ...

Main, ayrılmış bir sözcük olmadığından ve bir tanımlayıcıyı tanımlamak için yukarıdaki açıklamaya göre main de geçerli bir tanımlayıcı ve java1234'tü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.