class Main {
public static void main(String[] args) {
System.out.println(isHanguel('안'));
System.out.println(isHanguel('녕'));
System.out.println(isHanguel('하'));
System.out.println(isHanguel('세'));
System.out.println(isHanguel('요'));
System.out.println(isHanguel('.'));
}
static boolean isHanguel(char c) { //한글인지 검사
return c >= '가' && c <= '힣';
}
System.out.println(isHanguel(' ')); 처럼 공백은 가능한데
System.out.println(isHanguel('')); 는 안됨
char c1 = 'a';
c1은 'a'를 저장
String s1 = "a";
s1은 'a'를 가지고 있는 주소를 저장
class Main {
public static void main(String[] args) {
char c1 = 'a';'
char c2 = 'a';'
System.out.println(c1 == c2); // true
// String 은 char의 순서있는 조합이다.
String s1 = "하하";
String s2 = "하";
s2 += "하";
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
}
}
s1, s2는 내용은 같아도 서로 다른 객체가 같은 내용을 가지고 있기 때문에 다름
public class Main {
public static void main(String[] args) {
Person p1 = new Person(13);
Person p2 = new Person(13);
System.out.println(p1);
System.out.println(p2);
System.out.println("p1 == p2 : " + (p1 == p2)); // 리모콘 끼리 비교, 당연히 false
System.out.println("p1.equals(p2) : " + p1.equals(p2)); // 객체끼리 비교, 하지면 여기서는 Person 클래스에 equals 메서드를 오버라이드 하지 않아서 false
// 즉 객체 비교를 하려면 해당 클래스에 equals 메서드를 오버라이드 해야 한다.
String s1 = "하하"; // 문장객체 생성됨
String s2 = "하하"; // 여기서는 기존의 객체의 리모콘만 리턴, 이유 : 메모리 절약
System.out.println("s1 : " + s1);
System.out.println("s2 : " + s2);
System.out.println("s1 == s2 : " + s1 == s2);
System.out.println("s1.equals(s2) : " + s1.equals(s2));
String s3 = new String("하하"); // 재활용 x
String s4 = new String("하하"); // 재활용 x
System.out.println("s3 : " + s3);
System.out.println("s4 : " + s4);
System.out.println("s3 == s4 : " + s3 == s4);
System.out.println("s3.equals(s4) : " + s3.equals(s4));
}
}
class Person {
private int age;
public Person(int age) { this.age = age; }
}
String s1 = "하하";
String s2 = "하하";
자바는 메모리를 절약하기 위해 최대한 같은 것은 안만드려고 함(재활용) -> 기존의 객체의 리모콘만 리턴
-> 같
String s1 = new String("하하");
String s1 = new String("하하");
new String을 사용하여 생성했을 경우에는 재활용하지 않음 (일반적으로 사용x)
class Main {
public static void main(String[] args) throws IOException {
String s = "*";
s+="*";
s+="*";
System.out.println(s);
//StringBuilder가 더 좋음
StringBuilder sb = new StringBuilder();
sb.append("*");
sb.append("*");
sb.append("*");
System.out.println(sb.toString());
}
}
StringBuilder - "*"
하나만 가지고 있다가 마지막에 합침. 메모리 절약
객체의 출력 방식을 커스터마이즈. 디버깅이 편함
toString메서드는 객체가 문장으로서 취급되어야 할 때, 자바에서 알아서 호출해준다.
// Object 클래스와 toString
class Main {
public static void main(String[] args) {
사람 a사람1 = new 사람("홍길동", 22);
사람 a사람2 = new 사람("홍길순", 23);
System.out.println(a사람1);
System.out.println(a사람2);
}
}
class 사람 extends Object {
String 이름;
int 나이;
사람(String 이름, int 나이) {
this.이름 = 이름;
this.나이 = 나이;
}
@Override //어노테이션. 주석 같은 느낌
public String toString() {
return "사람[이름=" + 이름 + ",나이=" + 나이 + "]";
}
}
a사람1에 대한 이름, 나이
가 바로 출력되도록 하려면 Object클래스의 toString()을 사용
a사람1.이름
a사람1.나이
대신 a사람1
만 넣어도 실행 가능
static 메서드는 오직 static메서드나 static 변수에만 접근이 가능하다.
class Main {
public static void main(String[] args) {
사람.걷다();
사람.걷다();
사람.걷다();
}
}
class 사람 {
//int 속도 = 3; // instance(대리점)
static int 속도 = 3;
// static(본사) 메서드
static void 걷다() {
System.out.println("걷는다 : 속도(" + 속도 + "km/h)"); // 불가능(x)
숨쉬다(); // 가능
생각하다(); // 불가능(x)
}
static void 숨쉬다() {
System.out.println("숨쉬다.");
}
static void 생각하다() {
System.out.println("생각하다.");
}
}
static 사용 안할 시, new 사람().걷다();
자바의 모든 객체와 비객체는 Object형 변수에 연결될 수 있다.
원래 코드 : 저장소 계열의 클래스들이 비슷함. 중복되는 코드가 많음.
class Main {
public static void main(String[] args) {
Int저장소 a저장소1 = new Int저장소();
a저장소1.setData(30);
int a = a저장소1.getData();
System.out.println(a);
Double저장소 a저장소2 = new Double저장소();
a저장소2.setData(5.5);
double b = a저장소2.getData();
System.out.println(b);
사과저장소 a저장소3 = new 사과저장소();
a저장소3.setData(new 사과());
사과 c = a저장소3.getData();
System.out.println(c);
}
}
class Int저장소 {
Object data;
int getData() {
return (int)data;
}
void setData(Object inputedData) {
this.data = inputedData;
}
}
class Double저장소 {
Object data;
double getData() {
return (double)data;
}
void setData(Object inputedData) {
this.data = inputedData;
}
}
class 사과 {
}
class 사과저장소 {
Object data;
사과 getData() {
return (사과)data;
}
void setData(Object inputedData) {
this.data = inputedData;
}
}
개선한 코드1 : Object를 사용하여 저장소 클래스들을 하나로 통합함. 사용자 입장에서 데이터를 받을 때 매번 형변환을 해야하는 불편함이 있음.
class Main {
public static void main(String[] args) {
저장소 a저장소1 = new 저장소();
a저장소1.setData(30);
int a = (int)a저장소1.getData(); //int 형변환 해줘야함
System.out.println(a);
저장소 a저장소2 = new 저장소();
a저장소2.setData(5.5);
double b = (double)a저장소2.getData(); //double 형변환 해줘야함
System.out.println(b);
저장소 a저장소3 = new 저장소();
a저장소3.setData(new 사과());
사과 c = (사과)a저장소3.getData(); //사과 형변환 해줘야함
System.out.println(c);
}
}
class 저장소 {
Object data;
Object getData() {
return data;
}
void setData(Object inputedData) {
this.data = inputedData;
}
}
class 사과 { }
##개선한 코드2 : 제너릭을 이용하여 각 저장소 클래스들을 하나로 통합한 것만 아니라, 사용할 때도 편리
class Main {
public static void main(String[] args) {
저장소<Integer> a저장소1 = new 저장소<>();
a저장소1.setData(50);
int a = a저장소1.getData();
System.out.println(a);
저장소<Double> a저장소2 = new 저장소<>();
a저장소2.setData(5.5);
double b = a저장소2.getData();
System.out.println(b);
저장소<사과> a저장소3 = new 저장소<>();
a저장소3.setData(new 사과());
사과 c = a저장소3.getData();
System.out.println(c);
}
}
class 저장소<T> {
Object data;
T getData() {
return (T)data;
}
void setData(T inputedData) {
this.data = inputedData;
}
}
class 사과 {
}
저장소<Integer> a저장소1 = new 저장소<>();
형태 알기
import java.util.InputMismatchException;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int input = 0;
while ( true ) {
System.out.printf("숫자 : ");
try {
input = sc.nextInt(); // 대기, 숫자 하나 입력될 때 까지
break;
}
catch ( InputMismatchException e ) {
sc.nextLine(); // 버퍼를 비운다.
System.out.println("숫자를 입력해주세요.");
}
}
System.out.printf("입력된 숫자 : %d\n", input);
sc.close();
}
}
Scanner sc = new Scanner(System.in);
대신
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
사용 가능