Java'da Giriş almak için neden Tarayıcı Sınıfı örneğine ihtiyacımız var?


10

Java nesne yönelimlidir, ancak neden girdi almak için Tarayıcı Sınıfından bir nesne oluşturmamız gerekir? Could next()yöntemler, örneğin, sadece statik olabilir mi?

C sadece kullandığın kadar basit görünüyor scanf(), gets()ya da fgets(). Java geliştiricilerinin Tarayıcı sınıfını oluşturmasının bir nedeni olduğundan eminim, ancak işi yapmak için normal bir işleve sahip olmaktan daha iyi ne olabilir?

Aynı soruyu soran bu bağlantıyı buldum , ancak cevaplar hemen hemen

"statik olmadığı için bir nesne oluşturmanız gerekiyor" ...

Tahminim: Java Nesneye Yönelik olduğu için, tüm giriş yöntemlerini bir sınıfa koymaya karar verdiler. Statik yöntemler yapmadılar, böylece farklı nesnelerde her türlü farklı kaynağa (klavye girişi, dosya girişi ...) sahip olabilir misiniz?

Birinin soruyu daha net hale getirmek için düzenlemeyi yapıp yapamayacağını takdir ediyorum!

Yanıtlar:


34

Cevap "çünkü bir tarayıcı durumu vardır."

Java.util.Scanner koduna baktığınızda, bir tampon ve onunla ilişkili bilgiler, bir Eşleştirici, bir Desen, bir giriş kaynağı, kaynağın kapalı olup olmadığı hakkında bilgi, tür gibi bir dizi özel alan göreceksiniz. eşleşen son şey, son şeyin geçerli bir eşleşme olup olmadığı hakkında bilgi, sayılar için kullanılan sayı tabanı, yerel ayar ( bin ayırıcı kullanıp kullanmadığınız .veya ,binlik ayırıcı olarak kullanıp kullanmadığınız hakkında bilgi ) ve son kullanılan kalıplar için kendi LRU önbelleği , karşılaşılan son istisna hakkında bilgi, sayıları ayrıştırma hakkında bazı bilgiler, booleans ayrıştırma hakkında bazı bilgiler, tamsayıları ayrıştırma hakkında biraz daha fazla bilgi ... ve bence bu konuda.

Gördüğünüz gibi, bu oldukça büyük bir metin bloğu. Tarayıcının durumu budur. Tarayıcıyı statik bir sınıfa dönüştürmek için bu durumun başka bir yerde saklanması gerekir. Bunu yapmanın C şekli gerçekten onunla o kadar da fazla bir duruma sahip değil. Bir tane var fscanf. DOSYA, bulunduğu konum hakkında bir durum korur (ancak her çağrılması için aktarılması gerekir fscanf). Bir hata varsa, bunu işlemek zorunda (ve sonra gibi görünüyor o kod yazmaya başlamadan bu ) - ve bu size gibi bilgileri söylemez "Ben bir Tamsayı bekliyordum, ama bir dize buldum."

Teorik olarak statik Tarayıcıya bakıldığında - tüm durum sınıfın dışında tutulur, sınıf içinde kapsüllenmez. Diğer kod parçaları bu değişkenlerle uğraşabilir. Diğer kod sınıfın durumunu değiştirebilirse, sınıfın herhangi bir durumda ne yapacağını düşünmek çok zorlaşır.

Belki şöyle bir şey yazabilir ScannerState { Locale loc; ... }ve sonuç veren bir koda sahip olabilirsiniz:

ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);

Ama sonra, bu durum ilk etapta bir Tarayıcı nesnesi içinde kapsüllenmiş durumdan (ve eyaletten geçmesine gerek kalmadan) çok daha hantaldır.

Son olarak, Tarayıcı arabirimi uygular, Iterator<String>bu da kişinin aşağıdaki gibi kodda kullanabileceği anlamına gelir:

Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }

Scanner sınıfının bir örneğini alamadan, bu tür yapı nesneye yönelik bir dilde daha hantal hale gelir.


1
Yazdığınız her şey kesinlikle doğrudur, ancak InputStream'in sadece Tarayıcı değil durumu da vardır. Giriş konsoldan geliyorsa, C gibi, giriş almaya başlamak için herhangi bir parametre iletmeniz gerekmez. Ben hangi nasıl yapıldığını diğer akışları ile tutarlı olması için bu şekilde yapıldığını varsayalım yok durumunu gerektirir.
Neil

@Neil InputStream FILE*, C'deki (konum durumu) anlamına gelir .
cırcır ucube

1
Tarayıcı uygular Iterator- değil Iterable. Tarayıcıyı gelişmiş for döngüsünde kullanmak imkansızdır.
turbanoff

@ratchetfreak Kesinlikle. Bu "durum" FileInputStreams olmalıdır, ancak teknik olarak açık olduğundan konsoldan girdi için geçerli değildir.
Neil

1
@turbanoff Beni çağırdığın için teşekkürler. Düzelttim.

7

kısa cevap: bilmiyorsun. Tarayıcı örneği kullanmadan kullanıcı girişi alabilirsiniz.
Örneğin: https://docs.oracle.com/javase/tutorial/essential/io/cl.html veya
http://alvinalexander.com/blog/post/java/java-source-code-read-command-line -giriş


String orgName = (new BufferedReader(new InputStreamReader(System.in))).readLine();Bu, a'ya kıyasla çok kıvrımlıdır Scannerve aynı zamanda onları hemen atmak için bir değil iki nesneden oluşan yeni örnekler oluşturur.
Philipp

2
@Philipp, 1) Bu hantal, ama kesinlikle bir alternatif ve 2) örnekleri hemen atıyorsanız yanlış bir şey yapıyorsunuz (ya da gerçekten sadece bir satır konsoldan okumalısınız).
Arturo Torres Sánchez

Girişi okumak için Tarayıcıya ihtiyacınız yoktur. Ayrıca bir InputStreamReader'a ve bir BufferedReader'a ihtiyacınız yoktur. System.in'de "ham" akışla çalışabilirsiniz, tıpkı C'de olduğu gibi. Tarayıcı, bu akışı tüketmenin çok rahat bir yoludur.
Traubenfuchs
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.