분류:프로그래밍 언어 문법
이 문서의 원본은 외부 위키에서 가져왔습니다.
1. 개요[편집]
Java(자바)의 문법을 설명하는 문서다.
2. 기본[편집]
기본적으로 자바의 코드의 구조는 다음과 같다.
[package 이름 명시 (필수는 아님)]
[import할 패키지 명시]
[주요 클래스 구현]
[부차적 클래스 및 함수 구현]
클래스 선언 시에 *.java 파일의 이름과 동일한 이름으로 클래스 이름을 정해야 한다. HelloWorld.java 파일에서는 주요 클래스의 이름이 HelloWorld이여야 한다. 부차적 클래스의 이름을 정할 때에는 상관없다.
하나의 *.java 파일 안에는 하나의 주요 클래스만 정의되어야 한다.
C-족 언어답게 아주 기본적인 문법들은 C와 거의 동일하다. for-문, while-문, switch문, if-else if-else문, 산술 연산자 등. 여기에도 그런것들을 다 적으면 중복이 되니까 C언어/문법을 참고하도록 하자. 다만 자바는 포인터를 제공하지 않으므로 포인터에 관한건 다 무시해주자.
[package 이름 명시 (필수는 아님)]
[import할 패키지 명시]
[주요 클래스 구현]
[부차적 클래스 및 함수 구현]
클래스 선언 시에 *.java 파일의 이름과 동일한 이름으로 클래스 이름을 정해야 한다. HelloWorld.java 파일에서는 주요 클래스의 이름이 HelloWorld이여야 한다. 부차적 클래스의 이름을 정할 때에는 상관없다.
하나의 *.java 파일 안에는 하나의 주요 클래스만 정의되어야 한다.
C-족 언어답게 아주 기본적인 문법들은 C와 거의 동일하다. for-문, while-문, switch문, if-else if-else문, 산술 연산자 등. 여기에도 그런것들을 다 적으면 중복이 되니까 C언어/문법을 참고하도록 하자. 다만 자바는 포인터를 제공하지 않으므로 포인터에 관한건 다 무시해주자.
3. 편집 지침[편집]
소스 코드로 예시를 들 때
{{{#!syntax java (소스코드) }}} |
문법을 활용하여 소스코드를 써 주시기 바랍니다.
예시:
예시:
package myPackage;
import java.io.*;
public class myClass {
public static void main(String[] args) {
System.out.println("hello world!");
}
}4. 메인 클래스[편집]
4.1. 메인 메서드[편집]
자바 프로그램을 실행하려면 어떤 클래스 안에 있는 메인 메서드가 필요하다.
자바로 콘솔에 뭔가를 띄우려면 System.out.println() 메서드를 사용하자.
public class Namu {
public static void main(String[] args) {
System.out.println("Namu Wiki");
}
}자바로 콘솔에 뭔가를 띄우려면 System.out.println() 메서드를 사용하자.
4.2. 비메인 메서드[편집]
메인 메서드가 들어있는 클래스에 다른 정적 (static) 메서드를 써넣는게 가능하다. 양식은
접근자 static 반환형 이름(자료형 패러미터1, ...) {메서드 바디}
위에 있는 간단한 예제를 정적 메서드를 사용해서 구현해보자.
접근자 static 반환형 이름(자료형 패러미터1, ...) {메서드 바디}
위에 있는 간단한 예제를 정적 메서드를 사용해서 구현해보자.
public class Namu {
public static void main(String[] args) {
printNamu();
}
public static void printNamu() {
System.out.println("Namu Wiki");
}
}5. 클래스[편집]
5.1. 클래스 정의하기[편집]
당연하게도 커스텀 클래스를 만들수 있다. 예제를 통해 살펴보자.
클래스는 보통 각자 다른 .java 파일에 들어간다. 내부 클래스라는 개념이 있기는 하지만 그리 중요하진 않으므로 이 문단에서는 무시하자.
클래스안에 비정적 메서드는 'static'을 생략한다. static과 non-static 메서드의 차이점은 간단하다. static 메서드는 객체에 상관없이 호출이 가능하다. 하지만 non-static 메서드는 특정 개체를 대상으로 호출해야 한다. non-static 메서드를 호출하려면 object.method()로 호출, static 메서드는 class.method()로 호출하자.
클래스는 보통 각자 다른 .java 파일에 들어간다. 내부 클래스라는 개념이 있기는 하지만 그리 중요하진 않으므로 이 문단에서는 무시하자.
// Person.java
public class Person {
private String name; // 사람의 이름. 모든 객체가 각자 name을 얻는다.
private static String species = "Homo sapiens"; // 클래스에 하나만 있는 변수. 모든 Person 객체가 이걸 공유.
// 생성자 메서드. 객체를 생성할때 new 키워드와 함께 사용된다.
public Person(String name) {
// 자신의 변수를 참조할때 this를 쓸 수 있다.
this.name = name;
}
public String getName() {
return name; // this.name과 동일
}
public static String getSpecies() {
return species;
}
}
// Main.java
public class Main {
public static void main(String[] args) {
Person myPerson = new Person("John"); // 새로운 객체를 생성하려면 new 키워드를 사용하자
System.out.println(myPerson.getName()); // John
System.out.println(Person.getSpecies()); // Homo sapiens
}
}클래스안에 비정적 메서드는 'static'을 생략한다. static과 non-static 메서드의 차이점은 간단하다. static 메서드는 객체에 상관없이 호출이 가능하다. 하지만 non-static 메서드는 특정 개체를 대상으로 호출해야 한다. non-static 메서드를 호출하려면 object.method()로 호출, static 메서드는 class.method()로 호출하자.
5.2. 상속[편집]
상속을 하려면 extends 키워드를 사용하면 된다. 예제로 살펴보자.
자녀 클래스 내에서 상위 클래스의 메서드를 사용하고 싶다면 super 키워드를 사용하자. 참고로 이 예제에서 name을 사용하려고 하면 에러가 뜰 것이다. Person 클래스에서 name은 private 접근자를 가지는데, private 접근자를 가진 변수는 본 클래스 내에서만 직접 가져올 수 있다. Person 클래스에서 private String name;이 아니라 protected String name;을 쓰면 Student 클래스에서도 name을 자유롭게 사용할 수 있다.
// Student.java
public class Student extends Person {
private double gpa;
public Student(String name, double gpa) {
super(name); // 부모 클래스 Person의 생성자를 호출
this.gpa = gpa;
}
public double getGPA() {
return gpa;
}
}
// Main.java
public class Main {
public static void main(String[] args) {
Student joe = new Student("Joe", 4.0);
// Student는 Person이기도 하므로 Person의 getName() 메서드를 사용 할 수 있다.
System.out.println(joe.getName()); // Joe.
System.out.println(joe.getGPA()); // 4.0
}
}자녀 클래스 내에서 상위 클래스의 메서드를 사용하고 싶다면 super 키워드를 사용하자. 참고로 이 예제에서 name을 사용하려고 하면 에러가 뜰 것이다. Person 클래스에서 name은 private 접근자를 가지는데, private 접근자를 가진 변수는 본 클래스 내에서만 직접 가져올 수 있다. Person 클래스에서 private String name;이 아니라 protected String name;을 쓰면 Student 클래스에서도 name을 자유롭게 사용할 수 있다.
6. 자료형[편집]
int namu;namu라는 변수를 추가 한다.
namu = 3;같이 namu의 값을 정할 수 있다.
int namu = 3;시작과 동시에 저장 할 수도 있다.
System.out.println(namu);변수의 값을 출력 할 수도 있다.
namu = namuwiki;변수의 값을 이렇게 복사 할 수도 있다.
다음은 Java에서 기본적으로 제공하는 자료형이다.
6.1. 원시 자료형[편집]
primitive type. 자바에선 원시 자료형이 몇개가 있는데, 가장 중요한것 몇개를 뽑자면
- int: 정수 (-3, 2, 122...)
- double: 소수 (4.45, 1.0, 0.0...)
- char: ASCII 문자 (a, C, !...)
- boolean: 부울 (참, 거짓)
보다시피 원시 자료형 이름은 전부 소문자로 시작한다. 대문자로 시작한다면 원시 자료형이 아닌 참조 자료형, 즉 객체이다. 대표적인 예가 문자열인 String.
다음은 두 정수의 합을 반환하는 메서드이다.
public static int sum(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int n1 = 10;
int n2 = 12;
System.out.println(sum(n1, n2)); // 22
}6.1.1. byte,short,char[편집]
byte는 -128 ~ 127까지를 저장 할 수 있다.
short는 -32768 ~ 32767이다.
char은 유니코드로,0~ 65535이다.유니코드란 텍스트를 수로 바꾼 것이다.
면 namu는 65가 된다.A의 유니코드가 65기 때문이다.
short는 -32768 ~ 32767이다.
char은 유니코드로,0~ 65535이다.유니코드란 텍스트를 수로 바꾼 것이다.
char namu = 'A';면 namu는 65가 된다.A의 유니코드가 65기 때문이다.
6.1.2. int,long[편집]
int는 -2147483648 ~ 2147483647을 저장한다.
long은 -9223372036854775808 ~ 9223372036854775807을 저장한다.그리고 long의 값이 int의 범위 (-2147483648 ~ 2147483647)를 초과하면, 수 뒤에 l이나 L을 붙여야 한다.
long은 -9223372036854775808 ~ 9223372036854775807을 저장한다.그리고 long의 값이 int의 범위 (-2147483648 ~ 2147483647)를 초과하면, 수 뒤에 l이나 L을 붙여야 한다.
long namu = 1000000000000L;6.2. 래퍼 클래스[편집]
Java에서는 원시 자료형과 관련 내장 함수를 포함하는 래퍼 클래스가 존재한다. Java 5 이상이면 동일한 데이터 형식을 공유하는 원시 자료형과 래퍼 클래스 사이에는 자동적으로 박싱과 언박싱을 할 수 있다.
원시 자료형 | 래퍼 클래스 | 데이터 형식 |
- | Object | 임의의 데이터 형식[1] |
boolean | Boolean | 부울대수 (true 또는 false) |
byte | Byte | 1바이트 정수 |
short | Short | 2바이트 정수 |
int | Integer | 4바이트 정수 |
long | Long | 8바이트 정수 |
- | BigInteger | 무제한 크기의 정수 |
float | Float | 4바이트 소수 |
double | Double | 8바이트 소수 |
- | BigDecimical | 무제한 크기의 소수 |
char | String | 문자 |
6.3. 컬렉션[편집]
자바에서는 컬렉션을 통해 여러개의 데이터를 저장할 수 있는 자료구조를 제공한다. 컬렉션에는 저장된 데이터를 관리할 수 있는 내장 함수까지 구현되어 있다. 또한, 컬렉션 중에서 상속으로 구현된 것들도 있다.
컬렉션은 기본적으로 모든 데이터 형식을 사용할 수 있도록 일반화 된 변수를 지원한다. 표에서 [컬렉션]<X>에 있는 X가 일반화 된 변수를 뜻한다. 즉, X 대신에 int가 들어갈 수도 있고 String이 들어갈 수도 있고 사용자가 정의한 클래스가 들어갈 수도 있다.
컬렉션은 기본적으로 모든 데이터 형식을 사용할 수 있도록 일반화 된 변수를 지원한다. 표에서 [컬렉션]<X>에 있는 X가 일반화 된 변수를 뜻한다. 즉, X 대신에 int가 들어갈 수도 있고 String이 들어갈 수도 있고 사용자가 정의한 클래스가 들어갈 수도 있다.
컬렉션 | 상위 클래스 | 자료 구조 |
List<X> | - | 리스트 기본형 |
ArrayList<X> | List<X> | 가변 배열 구조의 리스트 |
LinkedList<X> | List<X> | 단순 연결 리스트 |
Map<X> | - | 맵 기본형 |
HashMap<X> | Map<X> | 값의 중복을 허용하지 않는 맵 |
LinkedHashMap<X> | Map<X> | 엔트리의 순서를 변경할 수 없는 맵 |
TreeMap<X> | Map<X> | 엔트리의 정렬이 가능한 맵 |
컬렉션 자료구조에 대한 정렬이나 필터링에 필요한 함수는 Collections 클래스 (java.util.Collections)에서 제공하고 있다.
6.4. 일반화 변수 형식[편집]
일반화 변수 형식 (Generic Variable Type)은 어떠한 데이터 형식이던 매개변수나 리턴값으로 사용할 수 있는 일반화된 자료형을 뜻한다. 자세한 내용은 아래 항목에서 설명하고 있으니 참조하면 된다.
7. 일반화 프로그래밍[편집]
자바에서의 일반화 프로그래밍에 대한 간단한 서술.
7.1. 일반 메서드[편집]
메서드를 정의할때 패러미터 또는 반환 값을 미리 정해두지 않고 싶을때 사용한다. 일반 자료형은 주로 T나 U같이 대문자 알파벳을 사용한다. 일반 메서드를 사용하려면 일반 자료형을 <> 사이에 넣어주자. 여러개의 자료형을 사용하고 싶다면 사이에 콤마를 넣어주면 된다.
public static <T, U> T printAndReturn(T input1, U input2) {
System.out.println(input1 + " " + input2);
return input1;
}
public static void main(String[] args) {
System.out.println(printAndReturn("Namu", 10));
/* 결과 :
Namu 10
Namu
*/
}7.2. 와일드 카드[편집]
와일드카드 라는 것도 있다. 일반형 자료와 비슷하지만 간결한 대신 좀 제한적인 개념. 와일드카드를 나타내는 기호는 물음표 ("?").
아래의 두 메서드는 똑같은 일을 하는데, 전자는 위에서 소개했던 방식이고, 후자는 와일드카드를 사용한 방식이다.
보다시피 와일드카드가 읽기 약간 더 편하다. 따라서 가능하면 와일드카드를 사용하는게 좋다. 물론 그냥 일반 자료형을 사용해야 할때도 많다.
아래의 두 메서드는 똑같은 일을 하는데, 전자는 위에서 소개했던 방식이고, 후자는 와일드카드를 사용한 방식이다.
public static <T> int getLength1(List<T> myList) {
return myList.size();
}
public static int getLength2(List<?> myList) {
return myList.size();
}보다시피 와일드카드가 읽기 약간 더 편하다. 따라서 가능하면 와일드카드를 사용하는게 좋다. 물론 그냥 일반 자료형을 사용해야 할때도 많다.
7.3. 바운딩[편집]
부등호 괄호안에 "extends" 또는 "super" 키워드를 사용하는 것. 이러므로써 자료형에 약간 제약을 걸 수 있다. 예를 들어서 <T extends Person>는 Person클래스 또는 Person을 상속하는 클래스를 뜻한다. 이때 상속은 직접적인 상속이 아니어도 된다. 예를 들어서 Person ← Student ← HighSchooler 이런식으로 상속관계가 있다면 HighSchooler도 T extends Person의 조건을 만족한다. 하지만 String 같은 자료형은 만족하지 못한다.
"super"은 그와 반대다. <? super Student>라 하면 Student 클래스 또는 그의 부모/조상 클래스들을 의미한다. super는 오직 와일드 카드만이 쓸 수 있다.
예로 리스트에 담긴 숫자의 (부동 소숫점) 합을 구하는 메서드를 보자.
"super"은 그와 반대다. <? super Student>라 하면 Student 클래스 또는 그의 부모/조상 클래스들을 의미한다. super는 오직 와일드 카드만이 쓸 수 있다.
예로 리스트에 담긴 숫자의 (부동 소숫점) 합을 구하는 메서드를 보자.
// 일반 자료형
public static <T extends Number> double sum1(List<T> list) {
double sum = 0;
for (T num: list) {
sum += num.doubleValue();
}
return sum;
}
// 와일드 카드
public static double sum2(List<? extends Number> list) {
double sum = 0;
for (Number num: list) {
sum += num.doubleValue();
}
return sum;
} 7.4. 일반 클래스[편집]
객체지향에 매우 충실한 언어답게 클래스를 짤때도 일반화 프로그래밍이 가능하다. 클래스 이름 뒤에 일반 자료형(들)을 <>안에 넣어주면 된다. 예를들면
// Wrapper.java
public class Wrapper<T> {
private T content;
public Wrapper(T content) {
this.content = content;
}
public T getContent() {
return this.content;
}
}
// ... 메인 메서드 안
Wrapper<String> myWrapper1 = new Wrapper<>("Namu Wiki"); // new Wrapper뒤에 꼭 <>을 붙여주자.
Wrapper<Integer> myWrapper2 = new Wrapper<>(44);
System.out.println(myWrapper1.getContent()); // Namu Wiki
System.out.println(myWrapper2.getContent()); // 448. 인터페이스[편집]
Interface. 일부 다른 언어에서는 프로토콜 (Protocol)이라고도 한다. 상속과 다르면서도 미묘하게 비슷한 개념. 상속이 어느 클래스의 속성과 메서드를 '상속'한다면, 인터페이스는 어떤 클래스가 '구현'해야 한다.
8.1. 인터페이스 정의하기[편집]
"interface" 키워드를 사용한다. 인터페이스를 만들때는 주로 추상 메서드만을 사용한다. 추상 메서드란 이 인터페이스/클래스에서 정의하지 않고, 구현/상속한 클래스에서 정의하는걸 말한다. 클래스에서는 추상 메서드를 만드려면 abstract 키워드를 붙여야하지만 인터페이스에서는 abstract가 디폴트다. Java 8부터는 비추상 메서드를 'default' 키워드를 써서 정의할 수 있다.
인터페이스 내의 변수 (예제의 "interfaceName")는 디폴트로 static final이다. 어느 한 객체에 붙어있지도 않고 다른 변수를 대입할 수도 없다는 뜻.
// Incrementable.java
public interface Incrementable {
String interfaceName = "Incrementable";
public void increment();
public default void printMessage() {
System.out.println("디폴트 메서드");
}
}인터페이스 내의 변수 (예제의 "interfaceName")는 디폴트로 static final이다. 어느 한 객체에 붙어있지도 않고 다른 변수를 대입할 수도 없다는 뜻.
8.2. 인터페이스 구현하기[편집]
'implements' 키워드를 사용한다.
이제 Person은 Incrementable 인터페이스를 구현했다. 이제 다음과 같은 메서드에 Person 객체를 보낼 수 있다.
단 한개의 클래스를 상속할 수 있는것과는 달리 하나의 클래스가 여러 인터페이스를 구현할 수 있다. 구현과 상속을 동시에 할 수도 있다.
public class Person implements Incrementable {
/* 생략 */
// Incrementable의 모든 추상 메서드를 정의
public void increment() {
age = age + 1;
}
}이제 Person은 Incrementable 인터페이스를 구현했다. 이제 다음과 같은 메서드에 Person 객체를 보낼 수 있다.
public static void example(Incrementable implementation) {
implementation.increment();
implementation.printMessage();
}단 한개의 클래스를 상속할 수 있는것과는 달리 하나의 클래스가 여러 인터페이스를 구현할 수 있다. 구현과 상속을 동시에 할 수도 있다.
public class SubClass extends SuperClass implements IntOne, IntTwo, IntThree {
// ...
} 8.3. 함수형 인터페이스[편집]
Java 8에 추가된 개념. 단 하나의 추상 메서드를 가지는 인터페이스를 말한다. 람다식을 지원하는 Java 8부터는 매우 특별한 취급을 받는다.
[1] Object 클래스는 모든 클래스의 최상위 클래스이다.