Java Programının Çalışma Mantığı:

Programcı Java kodunu yazar. “.java” dosyası olarak kaydedilir.. Bu kod Java derleyicisi (eclipse vb.) ile derlenir. Sonuçta bytekod adı verilen (“.class” uzantılı) bir tür makine kodu ortaya çıkar. Platform bağımsızlığını sağlayan şey bytecode’ dur. Çünkü bir kere bytecode oluştuktan sonra yazılım sanal makine içeren tüm işletim sistemlerinde (Windows, Linux vb.) çalışabilir.
Java Virtual Machine (Sanal Java Makinesi) adım adım bytecode’ ları işletir.
Java Sun Microsystem mühendislerinden James Goslig tarafından 1996 yılında geliştirilmeye başlamış; – açık kodlu,

Java, Nesne Yönelimli (Object – Oriented) bir dildir. Nesne Yöenlimli, bir düşünce şeklidir. Projedeki herşeyi nesneye yönelik olarak madelleriz. Herşey bir nesne olarak kabul edilir. İçerisinde bilgi saklayan herşey Nesneye dönüştürme potansiyeline sahiptir.
Java projesini nesneye yönelik modellemek programcının yeteneğine bağlıdır. Burada önemli olan nesneler arasındaki ilişkiyi modellemekdir. Örneğin kedi bir hayvan türüdür. Burada kedinin taşıması gereken özellikler (ismi, cinsi, kilso vb.) vardır. Yani kedi bir class dır, Nesneler ise kedi den türetilen özelliklerdir.
Örneğin Banka otomasyon projesi düşünelim. Burada müşteri bir bankanın unsurudur, varlıktır. Class’ lar; tür, unsur tanımı yapılan yerlerdir. Nesneler ise o türden, tanımdan yaşayan örneklerdir.



Java’ da veri türleri 2’ ye ayrılır:
Arasındaki Farklar:
DİZELER
Dizeler, metin depolamak için kullanılır. Bir dize, çift tırnak işareti içine alınmış bir karakter koleksiyonu içerir. Dizler karakter dizisidir.
String metin = “Merhaba” ;
İnt x = metin.length() ;
System.out.println(“ metin’ in uzunluğu : “ + x );
Length(): Dizenin(metnin) karakter(eleman) sayısını verir. Boşluklarıda sayar.
Trim(): Dizenin başındaki ve sonundaki boşlukları siler.
toUpperCase(): Dizedeki tüm harfleri büyük harflere çevirir.
toLowerCase(): Dizedeki tüm harfleri küçük harflere çevirir.
indexOf(): Dize içerisinde bir dize bulmamızı sağlar. Boşlukta dahil olmak üzere bi dizr içinde belirtilen bir metnin ilk konumunu söyler.
charAT(n): Dize içinde n. Elemanı(karakteri) bulur.
Substring(): tanımlanan indis numarasından sonra ekrana yazdırma işlemini gerçekleştirir. Parametre kullanırken başlangıç ve bitiş indis değerlerini substring(parametre1, parametre2) şeklinde belirtirsek girilen indis aralığındaki metni alır.
Concat(): 2 dizeyi birleştirmek için kullanılır.
startsWith(): Metin’ in ilk karakterini kontrol eder. True or False değeri döndürür. Büyük – küçük harf duyarlıdır.
Örnek:
String txt = “merhaba, java öğreniyorum” ;
System.out.println(txt.toUpperCase()); // MERHABA, JAVA ÖĞRENİYORUM
System.out.println(txt.toLowerCase()); // merhaba, java öğreniyorum
System.out.println(txt.indexOf(“java”)); // 10
System.out.println(txt.startsWith(“m”)); // true
NOT: Dizeleri birleştirmek için “+” operatörü kullanılır.
DÖNGÜLER
WHİLE
While (condition) { code block to be executed }
Örnek:
İnt İ = 0 ;
While (i<5) {
System.out.println(i);
İ++ ;
}
DO / WHİLE
Bu döngü koşulun doğru olupp olmadığını kontrol etmeden önce kod bloğunu bir kez yürütür, ardından koşul doğru olduğu sürece döngüyü tekrarlar.
Do { // kod bloğu
} While (condition)
Örnek:
İnt i = 0 ;
Do { System.out.ptrintln(i);
İ++ ;
} while(i<5);
FOR
For(int i =0; i<n; i++) {
// code block to be executed
}
DİZİLER(ARRAYS)
Diziler, her bir değer için ayrı değişkenler bildirmek yerine, tek bir değişkene birden fazla değer depolamak için kullanılır.
String[] adlar = {“Engin”, “Ali”, “Ece”};
Veya
String[] adlar = new String[3];
adlar[0] = “Engin”;
adlar[1] = “Ali”;
adlar[2] = “Ece”;
Örnek:
String [] Araba = { “Volvo”, “BMW”, “Ford”, “Skoda” };
Araba [0] = “Volvo”;
Araba [1] = “BMC” ;
Araba [2] = “Ford” ;
Araba [3] = “Skoda” ;
Length: Bir dizinin kaç elemanı olduğunu bulmak için kullanılır.
Dizilerde Döngü Kullanımı: For-Each()
String [] Araba = { “Volvo”, “BMW”, “Ford”, “Skoda” };
For (int i = 0; i<Araba.length; i++) {
System.out.prinln(Araba[i]);
For (type variable: arrayname) { code block to be executed }
Örnek:
String [] Araba = { “Volvo”, “BMW”, “Ford”, “Skoda” };
For (String i:Araba) {
System.out.println(i);
}
Örnek: Dizideki elemanların toplamını bulan program.
public class Main {
public static void main(String[] args) {
double[] mylist = {1.2,1.3,4.3,5.6} ;
double total = 0 ;
for (double i:mylist) {
total = total +i;
System.out.println(i);
}
System.out.println (“Toplam = ” + total);
}
}
Çok Boyutlu Diziler:

String [][] sehirler = new String [2][2];
sehirler[0][0] = “İstanbul” ;
sehirler[0][1] = “Bursa” ;
sehirler[1][0] = “Kocaeli” ;
sehirler[1][1] = “Ankara” ;
veya
String [][] sehirler = {{“İstanbul”,”Bursa”},{“Kocaeli”,”Ankara”}};
NOT: Çok boyutlu diziler Matris yapılarında daha çok kullanılır.
Örnek: Çok boyutlu dizileri yazdırma.
String [][] sehirler = {{“İstanbul”,”Bursa”,”Adana”},{“Kocaeli”,”Ankara”,”Konya”}};
for (int i = 0;i<sehirler.length;i++){
for(int j=0; j<sehirler[i].length;j++){
System.out.println(sehirler[i][j]);
}
}
METHODLAR (FONKSİYONLAR)
Fonksiyon(Metod) yalnızca çağrıldığında çalışan bir kod bloğudur. Parametre olarak bilinen verileri bir fonksiyona aktarabiliriz.
Public class myclass {
Public static void myfunction() { kod bloğu }
}

Fonksiyonla ile bir kod bloğunu çok defa yazmaya veya bir kod bloğunda değişiklikleri birçok defa yapmaya gerek kalmaz. Fonksiyonlar sayesinde programımızı küçük parçalar halinde yazabilir ve bu parçaları birleştirebiliriz.
Fonksiyonlar bizim ana programımızı yöneten main() fonksiyonunun yükünü azaltır.
Örnek:
public class Method {
static int topla(int x,int y) {
return x+y;
}
public static void main(String[] args) {
int z = topla(5,3);
System.out.println(z);
}
}

Örnek:
public class Method {
public static int topla(int…sayilar) {
int toplam =0;
for (int sayi:sayilar) {
toplam = toplam +sayi;
}
return toplam;
}
public static void main(String[] args) {
int toplam = topla(2,3,9,5);
System.out.println(toplam);
}
}
Mülakat Sorusu: Java Pass-By-Value mudur Pass – By-Reference midir?
Java Dili Pass – By- Value’ dur. Çünkü bir methoda parametre olarak bir değişkenin ya da bir instance değişkenin referansı parametre olarak verilmez. Kendisi parametre olarak verilir. Yani Java da metot a değişkenin kendisi verilir.
Mülakat Sorusu: Eşittir (=) ile equals()’ ın Farkı Nedir?
=(Eşittir) primitive(ilkel) değişkneler için kullanılır. Equals() Nan-primitive tipleri karşılaştırır.
JAVA DA SINIF (CLASS) VE NESNE YAPISI

UYARI: Sınıf (class) adı ile dosya adı aynı olmak zorundadır.
Sınıf (class) demek OOP(Nesne Yönelimli Program) demektir.
Sınıflar, nesnelerimiz için genel özellikler tanımladığımız yapılardır.
Sınıf ( class) soyut bir veri tipidir. (Nesne(Object) sınıf kavramını soyutlaştırır. Örneğin kedi bir türdür yani bir sınıftır. Ama evde beslediğimiz kediyi bu sınıfın bir nesnesi olarak düşünebiliriz.
Kedi Sınıfı : Mayıs, Mırmır, Minti (Kedi sınıfının nesneleridir).
Bir Java sınıfı kendi özelliklerini belirleyen, değişkenleri ve fonksiyonları içeren bir birimdir.
Java programları class lardan oluşur. Bütün sınıflar aynı yapıya sahiptir. Aralarındaki fark içerdikleri değişkenler ve metodlardır.
Bir sınıftaki değişkenler o sınıfın niteliklerini, metodlar ise o sınıfın davranışlarını belirler.

Sınıf yapısı büyük bir kod bloğunu gruplamamızı, bu sayede kodlara kolay ulaşmamızı sağlar.

Nesne yönelimli programlamanın prosedürel programlamaya göre birçok avantajı vardır:
Bir sınıf, nesneler için bir şablondur ve bir nesne bir sınıfın örneğidir.
Tek tek nesneler oluşturulduğunda, sınıftaki tüm değişkenleri ve yöntemleri devralırlar.
Final: Final anahtar kelimesi, her zaman aynı değer de kalmasını istediğimiz değişkenler için kullanılır. Örneğin Pİ sayısı(3.14159 … ) gibi. Final olan Class’ lar extend edilemezler yani genişletilemezler. Final olan Metotlar Override edilemezler. Final olan bir field için ya başlangıç değeri verilmeli ya da constructionlarda ilk değer ataması yapılmalıdır.
Static fonksiyonlar(Methodlar), oluşturuldukları sınıfın nesnesini oluşturmadan erişebileceğimiz fonksiyonlardır. Public fonksiyonları çağırabilmemiz için, oluşturuldukları sınıfın bir nesnesini oluşturmamız gerekir.
ENCAPSULATION (KAPSÜLLEME)
Her class(sınıf), özellik(attribute) yani field barındırır. Kapsülleme; dışardan erişilmesini istemediğimiz veya kimin erişmesini istediğimiz yapıya denir. Bu yapı erişim belirteçleri ile kullanılır. Yani Class içerisinde metot ve değişkenlerin erişimlerini belirleme ilkesidir.
Kapsülleme, hassas verilerin kullanıcılardan gizlenmesini sağlar.
Kapsülleme ile Sınıf özelliklerinin ve yöntemlerinin daha iyi kontrolü sağlanır.
NOT: Main.java, Product.Java ve ProductMAnager.java aynı package’ da(Klasör’ de) yer almak zorundadır.
ERİŞİM NİTELEYİCİLERİ
Java Programında Kapsülleme ile değişkenlere doğrudan erişim engellenebilir. Private ile değişkenlerin diğer sınıflardan çağrılması veya ulaşılması engellenebilir. Bunun sebebi güvenliktir. Değişkenlere doğrudan erişim engellendiği için belli kurallar bütünüyle erişim sağlanabilir. Bu erişim Get ve Set metotlarıyla mümkün kılınmıştır.
Public değişkenler kullanmak yerine, değişkenleri mümkün olduğunca private yapıp kodun içine GET ve Set metotları ekleyebiliriz.
Get ve Set Metotları sınıfın iç yapısını görüntülü hale getirir.

Getter ve Setter ile Çalışmak
Getter: Getirmek, almak. Get() metodu bir değer döndürmektedir. Böylece istediğimiz değişkenin değerine ulaşabiliriz.
Setter: Planlamak, düzenlemek. Set() metodu değer döndürmez ama parametre alır. Böylece değişkenin değerini değiştirebiliriz.
JAVA YAPICILARI (CONSTRUCTORS)
Yapıcı (Constructor), bir metot(fonksiyon) çeşididir. Bazen bir fonksiyonu çağırmaya gerek kalmadan, bir sınıftan nesne oluşturduğumuz anda bazı işlemlerin yerine getirilmesini isteriz. Buna ihtiyaç duymamızın nedeni büyük çapta projelerde fazla koddan kurtulmaktır. Burada yapıcı metotlar devreye girer.
Yapıcılar, nesne oluşturduğumuz anda çalıştırılan fonksiyonlardır. Amaç bir nesneyi ilk kullanımı hazırlamaktadır.
Yapıcıların erişim durumu mutlaka “public” olmalıdır.
Yapıcıların adı sınıf adıyla aynı olmalıdır.
Yapıcılar çağrılırken “new” anahtar sözcüğü kullanılır.
NOT: Yapıcılar, her nesnenin ilk üretildiği anda çalıştırılan fonksiyonlardır.
NOT: Yapıcılar da(Yapıcı methodlarda), return olmaz. Void özelliği gibi düşün.
KALITIM (ALT SINIF – ÜST SINIF) – İNHERİTANCE
Bir sınıftan miras(kalıtım) almak için “extends” anahtar sözcüğü kullanılır.
Alt sınıf(alt): Başka bir sınıftan miras alan sınıf.
Superclass(parent): Miras alınan sınıf(Üst sınıf)
Kalıtım(miras) yapısı, kodun tekrar kullanılabilirliği için faydalıdır. Yeni bir sınıf oluştururken mevcut bir sınıfın özelliklerini ve yöntemlerini yeniden kullanmamızı sağlar.
NOT: Kalıtım(miras), sınıflardaki ortak özellikleri ve metotları tekrar tekrar yazmamızı engeller yani kod kalabalığını engeller.
Örneğin, Çarpma işlemi yapan bir metod düşünelim. 1. çarpma işleminde 2 int değer, diğer metot da 3 float değer, başka bir çarpma metot unda 4 double değeri çarpabiliriz. Her çarpma işlemi için aynı isimde bir metot kullanabiliriz. Bu OverLoading’ dir.
Overridding; bir üst class daki çarpma metodunu, içindeki argümanları değiştirmeden aynı argümanlarla çağırıp kullanmaktır. Bu halde metot un imzası değişmez.
POLİMORFİZM (ÇOK BİÇİMLİLİK)
Bir nesnenin çok şekilli olarak kullanılabilmesidir. Bir sınıfı(classı) birden fazla şekilde parametre kabul edebilecek veya birden fazla şekilde cevap verebilecek şekilde program yapabilmemizi sağlar. Örneğin aynı isme sahip fonksiyonları istediğimiz kadar yazabiliriz. Şartımız fonksiyonun tipi veya parametresi değişecek.
Overriding inheritance olduğunda söz konusu olur yani faklı class daki aynı metodlardan bahsedilir. Overloading aynı class içerisinde isimleri aynı 2 metod varken kullanılır.
ABSTRACT(SOYUTLAMA) SINIFLAR
Ortak özellikleri olan nesneleri modellemek için Java dilinde abstract(soyut-belirsiz-muğlak) sınıflar kullanır. Soyut sınıflar oluşturulurken class ismi yerine “abstract class” kelimeleri kullanılır.
Soyut(abstract) sınıfı extend eden sınıf, soyut sınıfın tüm soyut metotlarını override etmek zorundadır.
Soyut(abstract) sınıfların içerisindeki soyut metotların gövdesi boş olması gerekir(Kullanılacak yere göre işlem farklılığı olacağından.)Ama soyut olmayan metotların gövdeleri olmak zorundadır.
Soyut sınıflar private olarak tanımlanamazlar. Çünkü kalıtım özelliğini her daim göstermek zorundadır(Zaten soyut sınıfların sihri bu).
INTERFACE(ARAYÜZ)
Interface kavramı abstract class kavramına benzerlik gösterir. Javada Çoklu Kalıtım Yapılamaz yani bir sınıf birden fazla sınıfı extends ile miras alamaz. Çoklu kalıtım yapabilmek için Arayüzleri (Interfaces) veya dahili sınıfları kullanırız (Abstract ile interfaces farkı). İnterfaces daha genel şeyleri kapsar(Boy: insan, bina, hayvan filan), Abstract daha birbirine bağlantılı şeyleri kapsar.(Yemek():insan ,hayvan bu kadar.)
Arayüzler (Interfaces) daha kullanışlı ve daha farklıdır.
Arayüzler, “interface” anahtar kelimesi ile tanımlanır.
Erişim belirtkesi ya public olur ya da hiç olmaz. Abstract’ lar private, protected değişken içerebilir.
Arayüzde sadece default ve static metodlar içerir.
Arayüz public olarak nitelenmişse içerisindeki tüm metot ve değişkenler otomatikten public olur.
Arayüzde yer alan tüm metotlar gövdesizdir yani abstract metotlar yer alır.
Arayüzde yazılan metotlar gövdesiz olduğu için yaptıkları iş belli değildir.
Değişkenleri genellikle final ve static olur çağıran sınıf değişkenleri direkt kullanır değerlerini değiştiremez. Abstract’ lar private, protected değişken içerebilir.
En güzel özelliği bir sınıfın birden fazla arayüzü implements ederek kullanabilmesidir.
Programlarımız üzerinde temel olarak kalıtım işlemini bir sınıf üzerinde birden fazla kalıtım gerçekleştirmek istiyoruz veya DRY (Don’t Repeat Yourself) prensibini kullanarak doğru bir kod dizisi yazmak istediğimiz zaman, yazdığımız koda esneklik, kod okunabilirliğini arttırmak istediğimiz zaman Java Interface kullanmamız gerekmektedir diyebiliriz.
Enums
Java dilinde Enum türleri önceden tanımlanmış sabit değerleri ifade etmede kullanılır. Örneğin gün, ay, renk, yön isimleri gibi. Enum türler dışarıdan new operatörü ile türetilemezler. Enumlar içinde yazılan yapıcı metotlar sadece enum sabitleri tarafından çağırılabilirler.
Java’da enum kavramı oluşturmuş olduğum programın okunabilirlik düzeyini arttırır ve sağlamış olduğu tip güvenliği ile daha stabil bir altyapı oluşturmaya olanak sağlar.
Bir enum, bir class gibi niteliklere ve methodlara sahip olabilir. Enum sabitleri otomatik olarak static ve final tanımlanırlar, yaratıldıktan sonra değiştirilemezler.
ARRAYLİST(KOLEKSİYONLAR)
Java ArrayList sınıfı öğeleri depolamak için dinamik bir dizi kullanır. Normal bir dizi gibidir fakat boyut sınırı yoktur. İstenildiği zaman öğe eklenir veya öğe silinebilir. Bu sayede esnek bir yapıya sahiptir.
Yerleşik bir dizi ile ArrayList Java’daki bir dizi arasındaki fark , bir dizinin boyutunun değiştirilememesidir (bir diziye eleman eklemek veya diziden eleman çıkarmak istiyorsanız, yeni bir tane oluşturmanız gerekir). Öğeler, ArrayList’ e istediğiniz zaman eklenebilir ve çıkarılabilir.
Java USER INPUT (Scanner)
importjava.util.Scanner;// Import the Scanner class
classMain{
publicstaticvoidmain(String[]args){
ScannermyObj=newScanner(System.in);// Create a Scanner object
System.out.println("Enter username");
StringuserName=myObj.nextLine();// Read user input
System.out.println("Username is: "+userName);// Output user input
}
}

Örnek: user input – scanner programı
importjava.util.Scanner;
classMain{
publicstaticvoidmain(String[]args){
ScannermyObj=newScanner(System.in);
System.out.println("Enter name, age and salary:");
// String input
Stringname=myObj.nextLine();
// Numerical input
intage=myObj.nextInt();
doublesalary=myObj.nextDouble();
// Output input by user
System.out.println("Name: "+name);
System.out.println("Age: "+age);
System.out.println("Salary: "+salary);
}
}

JAVA DATE İşlemleri
Java’nın yerleşik bir Tarih sınıfı yoktur, ancak java.timepaketi tarih ve saat API’sı ile çalışacak şekilde içe aktarabiliriz. Paket birçok tarih ve saat sınıfı içerir.

Geçerli Tarih için:
Geçerli tarihi görüntülemek java.time.LocalDateiçin sınıfı içe aktarın ve now()yöntemini kullanabiliriz.
Örnek:
importjava.time.LocalDate;// import the LocalDate class
publicclassMain{
publicstaticvoidmain(String[]args){
LocalDatemyObj=LocalDate.now();// Create a date object
System.out.println(myObj);// Display the current date
}
}
Çıktı: 2023-03-29
Geçerli Saat için:
Geçerli saati (saat, dakika, saniye ve nanosaniye) java.time.LocalTime görüntülemek için sınıfı içe aktarın ve now() yöntemini kullanabiliriz.
importjava.time.LocalTime;// import the LocalTime class
publicclassMain{
publicstaticvoidmain(String[]args){
LocalTimemyObj=LocalTime.now();
System.out.println(myObj);
}
}
Geçerli tarih ve saati görüntülemek java.time.LocalDateTime için sınıfı içe aktarın ve now() yöntemini kullanabiliriz.
Örnek:
importjava.time.LocalDateTime;// import the LocalDateTime class
publicclassMain{
publicstaticvoidmain(String[]args){
LocalDateTimemyObj=LocalDateTime.now();
System.out.println(myObj);
}
}

Yukarıdaki örnekte “T”, tarihi saatten ayırmak için kullanılır. DateTimeFormatterofPattern() Tarih-saat nesnelerini biçimlendirmek veya ayrıştırmak için sınıfı aynı paketteki yöntemle kullanabilirsiniz. Aşağıdaki örnek, tarih saatinden hem” T ” hem de nanosaniyeleri kaldıracaktır:
Örnek:
importjava.time.LocalDateTime;// Import the LocalDateTime class
importjava.time.format.DateTimeFormatter;// Import the DateTimeFormatter class
publicclassMain{
publicstaticvoidmain(String[]args){
LocalDateTimemyDateObj=LocalDateTime.now();
System.out.println("Before formatting: "+myDateObj);
DateTimeFormattermyFormatObj=DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
StringformattedDate=myDateObj.format(myFormatObj);
System.out.println("After formatting: "+formattedDate);
}
}

Örnek: 2 tarif arasındaki fark
DateTimeFormat.java
package tarifFark;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class DateTimeFormat {
public long fark(String t1, String t2) throws ParseException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd”);
LocalDate firstDate = LocalDate.parse(t1, formatter);
LocalDate secondDate = LocalDate.parse(t2, formatter);
long days = ChronoUnit.DAYS.between(firstDate, secondDate);
return days;
}
}
tarifFark.java
package tarifFark;
import java.text.ParseException;
public class tarihFark {
public static void main(String[] args) {
String t1 = “01 01 2023”;
String t2 = “01 03 2023”;
long fark = 0;
DateTimeFormat date = new DateTimeFormat();
try {
fark = date.fark(t1,t2);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(fark);
}
}
çıktı:
