2022-07-11 MON
inner class 형태
interface도 만들 수 있다.
원래 class
※ 참고 ※ Student.java 파일이 컴파일 => Student.class
inner Class 멤버 class => Studnet$Member.class 로 바뀐다.
/* Slack에서 주신 것 */
class A{ // 클래스 A 파일 만들고
class B{ // 클래스 B파일 만든다. => 멤버클래스
int field1;
void method1() {};
// static 필드 및 메소드는 사용불가
}
}
A a = new A();
A.B b = a.new B(); // 이런 형태로 만든다.
b.field1 = 3;
b.method1();
innerClass가 필요한 순간이 온다.
member Class
local Class
class Test {
public void method() {
class D{
int field1;
void method1() {};
}
D d = new D();
d.field1 = 5;
d.method1();
}
LocalTest 예시
public class LocalTest {
public void method(final int arg) {
final int localVal = 1;
// arg = 10;
// localVal = 100; 이유는 local 변수는 끝나면 stack에서 사라짐
//
class Inner {
public void method(){
int result = arg + localVal;
} // 여기 사이 update가 되면 안된다. 클로저로 카피할 대상은 final로 붙여놔야한다.
} // closer
inner in = new Inner();
}
// 언제든지 객체를 만들 수 있는데 클로저라 값을 가지고 있음.
// 값을 복사해 놓고 있는데 객체를 만드는데 문제는
// 값을 복사해갔는데 나중에라도
Button.java
ButtonMain.java
Calllistener.jave
예외
예외는 다음과 같이 jang.lang 패키지 있는 throwable 클래스의 자식객체로,
프로그램 실행중에 발생하는 일종의 이벤트이다.
1. 일반 예외
컴파일러 입장에서 예외가 발생할 수 있는 부분을 판단할 수 있다. 그런 부분은 반드시 예외처리를 해줘야한다.
exception을 상속받아서 만든다.
개발자의 실수로 발생할 수 있으며, 예외처리를 하지 않아도 컴파일할 수 있는 비검사형 예외이다.
2. 런타임 예외
예외처리를 하지 않으면 컴파일 오류가 발생하므로 꼭 처리해야하는 검사형 예외이다.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Exception.html
// JVM Java Virtual Machine의 줄인 말 = 자바를 실행시키기 위한 가상 기계(컴퓨터)
// OS에 종속 받지 않고, CPU가 JAVA를 인식, 실행
※ 실행 예외 예시 (런타임)
: 프로그램 실행 도중에 예외가 발생하면 JVM()은 해당 실행 예외 객체를 생성한다. 실행 외는 컴파일러가 예외처리 여부를 확인하지 않기 때문에 개발자가 예외처리 코드의 추가여부를 결정해야한다.
✔ NullPointerException
컴파일러는 알 수가 없어서 에러가 난다.
null 값을 가진 참조변수에 접근할 때 발생
✔ NullPointerException
argument를 주지 않아서 발생한다.
배열, 벡터 등에서 범위를 벗어난 인덱스를 사용할 때 발생
try - catch 문으로 에러메시지
catch 블록에 포함된 예외 처리 코드를 핸들러
✔ ArrayIndexOutOfBoundsException
catch로 에러 표시
printStackTrace() : Throwable 객체와 추적 정보를 화면에 출력한다.
※ 일반 예외
컴파일러 입장에서런타임 관계없이 컴파일러가 자체로 막아버리는 일반예외.....
Class.forName("jang.lang.String2")
실제로는 저렇게 쓰면 안된다. 예외처리를 정확하게 해줘야 한다.
finally : 예외발생과 관계없이 항상 실행한다.
public static이 아니라서 localClass에 에러가 뜬다.
그 이유는 메인 메소드가 static으로 올라가는 부분
객체가 생성된 다음에 접근할 수 있는 메소드인데 static안에서 인스턴스 접근이 불가능한데
static에서 static멤버밖에 접근 못하니깐.. static을 사용해야한다.!
이렇게 static을 써줘야 ...
throws는 익셉션 던져버리는 거
throws절은 예외를 처리하지 않고 발생한 예외 객체를 다른 곳으로 떠넘긴다.
즉, 현재 메서드에서 예외를 처리하지 않고 발생한 예외 객체를 다른 곳으로 떠넘긴다.
던지면 부모 클래스로 간다. 즉, 현재 메서드에서 예외를 처리하지 않고 현재 메서드를 호출한 곳으로 발생한
예외 객체 대신 처리해달라고 떠넘기는 것이다.
메서드에서 발생한 예외를 내부에서 처리하기가 부담스러울 때 throws 키워드를 사용해 예외를
상위 코드 블록으로 양도할 수 있다.
RuntimeException 생성자가 있으니 메시지를 받아서 찍어준다.
throws Bal~~ 에러 발생한 곳에서 잔고부족 던진다.
get 불러오는거
catch 잡히면 빠져나간다.
runtime에 있는 getmessage를 가져온거
catch 블록의 예외 객체가 나중 catch 블록 예외 객체의 부모라면, 앞에 있는 catch 블록이 먼저 가로채기 때문에
나중 catch 블록이 먼저 가로채기 때문에 나중 catch 블록은 쓸모가 없으므로 컴파일러는 오류를 발생시킨다.
따라서, 구체적인 예외를 먼저 처리해야한다.
자바의 모든 클래스는 object를 상속 받는데
equals method 오버라이드
문자열을 비교하게끔 한다.
.equals 를 원하는 상황에 따라 오버라이드 할 수 있다.
object 클래스에서 상속받은 equals() 메서드를 사용한다.
따라서 내용이 동일하더라도 다른 객체이기 때문에 false를 반환했던것.
equlas Override를 해야한다.
Member.java
MemberMain.java
※ 메소드 오버라이드
instanceof 내장함수 : 복사된 값이냐
앞에 있는 애가 뒤에 있는 값이 복사값이냐..
instanceOf 연산자는 객체가 어떤 클래스인지, 어떤 클래스를 상속받았는지 확인하는데 사용하는 연산자입니다.
equals를 override 한다.
우리가 받아온 obj가 멤버랑 같냐,, 순서 바뀌면 틀린다.
멤버 instance .. new
m1 == m2 로 나오는데,
m1 != m3
자바 연결- C++연결 없어지고 연결 없어지고 연결
계속 쓰다보면 속도가 느려지고 리소스가 많이 사용..
문자열 내용을 자주 변경한다면 String 클래스를 사용하는 것은 좋지 않다.
string은 불변의 속성을 갖고 있기 때문이다.
자바는 변경될 수 있는 문자열을 다룰 수 있도록 StringBuilder와 StringBuffer 클래스를 제공한다.
다중 스레드 환경에서 StringBuffer 클래스가 안전하다는 점을 제외하면 StringBuffer 클래스는 StringBuilder 클래스와 유사하다. 다라서 다중 스레드 환경이 아니라면 StringBuilder 클래스를 사용하는 것이 효율적이다.
- StringBuilder 객체는 내부에 문자열을 저장하는 버퍼가 있으며, 그 버퍼의 크기는 변할 수 있다.
매개변수 없는 디폴트 생성자를 사용해 STringBuilder 객체를 생성하면 16개 문자를 저장할 수 있는 버퍼를 생성
---- 검색한 내용
StringBuffer는 동기화 키워드를 지원하여 멀티스레드 환경에서 안전하다는 점(thread-safe)
StringBuilder는 동기화를 지원하지 않기 때문에 멀티쓰레드 환경에서 사용하는 것은 적합하지 않지만 동기화를 고려하지 않는 만큼 단일스레드에서의 성능은 StringBuffer 보다 뛰어납니다.
StringBuffer : 문자열 연산이 많고 멀티스레드 환경일 경우
StringBuilder : 문자열 연산이 많고 단일스레드이거나 동기화를 고려하지 않아도 되는 경우
API를 이용하여 동일 객체내에서 문자열을 변경하는 것이 가능
Thread Safe... 스레드 기능..간섭을 안한다.
Buffer를 쓰면 쭉 간다. 중간 사이에 못들어온다.
포장클래스
객체지향 언어는 캡슐화, 상속, 다향성등 특징이 많다.
그러나 기초 타입을 사용하면, 객체지향언어의 특징을 이용할 수 없다.
대부분의 기본패키지가 제공하는 클래스의 메서드는 참조타입을 매개변수로 사용하기 때문이다.
기초 타입 데이터를 포장해 객체화하는 것을 박싱이라고 하는데, 반대 과정을 언박싱이라고 한다.
int의 클래스가 Integer.. auto boxing= 같은 데이터 타입을 클래스로 넣어준다.
int와 char 타입에 대응하는 포장 클래스는 각각 Integer와 Character 이며, 나머지 포장클래스 이름은
기초 타입의 첫 영문자를 대문자로 바꾼 것이다.
문자열을 정수형
문자열을 더블형으로 바꾸는거
Integer 자동박싱..
package com.gyuone.javaapi;
import java.time.LocalDateTime;
public class WrapperExam {
public static void main(String[] args) {
Integer a = 100; // 자동으로 넣어주는 auto boxing 이라고한다.
System.out.println(a);
// 각각의 wrappe Class 감싸는 클래스를 만들었다.
// Byte Char Integer Short .... 이미 클래스를 만들어놨음
int val1 = Integer.parseInt("10"); // 문자열을 바꾸는 거
val1++;
System.out.println(val1);
double val2 = Double.parseDouble("3.14");
val2 *= 10;
System.out.println(val2);
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
StringBuilder sb = new StringBuilder();
sb.append(now.getYear());
sb.append("년 ");
sb.append(now.getMonthValue());
sb.append("월 ");
sb.append(now.getDayOfMonth());
sb.append("일 ");
sb.append(now.getDayOfWeek());
sb.append(" ");
sb.append(now.getHour());
sb.append("시 ");
sb.append(now.getMinute());
sb.append("분 ");
sb.append(now.getSecond());
sb.append("초 ");
sb.append(now.getNano());
sb.append("나노초");
System.out.println(sb.toString() + "\n");
}
}
import 해주기 ! slack 에서 보내주신거
스레드 : 한 가닥의 실
: 작업을 실행하는 코드의 흐름이 바느질할 때의 실처럼 이어진 것과 같기 때문이다.
하나의 프로세스는 하나 이상의 실행흐름을 포함시키기 때문에 프로세스는 적어도 하나의 스레드를 가진다.
프로그램 하나 띄우는 거 OS 입장에서 보면 프로세스(process)
메모장을 클릭하면, 하나의 프로세스를 실행시킨다는 의미
그런데 하나의 프로세스가 시스템 자원을 독차지하는 것은 매우 비효율적임.
메인 스레드가 하는 역할이 static영역의 thread ..
단일 스레드 형태로 메인 스레드가 동작
Thread 만드는 첫 번째 방법
: 자바 내장된 Thread 사용
FlagGame.java
FlagThread.java
자바 내장된 Thread 사용
문제점 : 다른 것을 extends 해야하는 상황이 생긴다면,
자바에서는 다중 상속이 안되기 때문에 보완하기 위해서는 다른 방법이 필요하다. -> 이때는 interface 사용
Thread 만드는 두 번째 방법
: Runnable 구현 클래스 정의
Runnable 구현 클래스에 스레드 실행 코드 추가...
FlagTask.java
FlagGame2.java
Runnable 구현 클래스 구현 정의
Runnable 구현 클래스에 스레드 실행 코드 추가
FlagThread.java
Runnable 인터페이스의 익명 구현 객체 사용!
FlagGame2.java
Runnable 인터페이스의 익명 구현 객체
스레드를 상속한 익명 자식객체..
Thread 자식 클래스 정의
thread.start();
스레드를 위한 자식 클래스가 정의되면 다음과 같이 자식 객체를 생성한다. 그런 다음 Thread 클래스의 메서드인 start()를 호출하면 작업스레드가 실행될 수 있다.
둘다 익명 자식객체. 익명 구현객체를 만들 수 있다.
스레드 이름 지정
ThreadA
setName으로 스레드 이름 지정
ThreadB
스레드이름을 지정 X 오버라이드만 허용..
스레드 이름을 지정해주지 않으면 Thread-1로 나온다. 스레드 이름을 지정해주면 디버깅하기 편하다.
Calculator.java
User1.java
User2.java
CalMain.java
두개의 스레드가 근소한 차이가 실행이 되면
Calculator 본인 스레드 이름을 각자 정하고 setMemory에 넣는다.
user1이 100 setting 필드 값 100 넣기
시간이 잡아 먹는 일을 하다가 50이 넣어오면 syso에 50이 넣어서
override된거 맞음.. setMemory에서 빠져나오지 못해서 발생..
두개 이상의 Thread가 동시에 진행.. -> 문제가 생길 수 있는 부분을 critical section
-> 다른 작업이 들어오지 못하게 막는다. 제일 간단한 방법
Calculator.java
synchronized : 이 키워드의 존재 여부에 따라 user1이 먼저 실행 되고 나서 user2가 다음에 실행된다.
작업1을 하고 작업2를 해서 시간이 조금 걸린다.
자바는 임계영역을 동기화하려고 synchronized 키워드를 제공한다. 스레드가 synchronized로 지정된 동기화 블록에 진입하면 lock을 걸고, 그 블록을 벗어날 때 lock을 푼다. 동기화 블록에 진입한 스레드가 코드를 실행할 동안 다른 스레드는 동기화 블록 앞에서 락이 풀릴때까지 대기해야한다. 그러므로 스레드 동기화는 하나의 스레드가 동기화 블록을 실행하면 그 스레드가 동기화 블록을 사용하려는 모든 스레드를 중지시킨다.
메서드에 키워드를 지정하거나 코드의 일부에 지정한다. 메서드 전체가 아니라 일부 영역만 임계 영역이라면 동기화 블록을 사용하는 것을 좋다.
멀티 스레드 환경에서도 안전하게 사용가능
StringBuilder
StringBuffer 사용법은 같다.
StringBuffer <= thread safe 방법이다.
Calculator.java
String을 받아서 사용가능하지만 귀찮으니 this를 쓰자. 강사님께서는 this를 쓰라고 하셨다.
스레드의 종료 여러가지 방법
방법1_ 무한루프로 돌고 있는 스레드를 안전하게 종료시키는 방법
stop flag를 걸어서 빠져 나온다.
stop() 메서드를 사용할 수 있지만, 호출 즉시 종료하므로 사용중인 자원을 불완전한 상태로 남겨 둔다.
따라서, 자바2부터는 stop() 메서드를 가급적으로 사용하지 않도록 권고한다.
스레드를 안전하게 종료하려면 반복문의 조건이나 interrupt() 메서드를 사용하지 않는 것이 좋다.
PrintThread.java
PrintMain.java
Console
돌던 거에 상태를 어디에 저장 t8 -> t1 다시 로드해서 돌려야한다.
context switching 이것도 오버헤드가 걸린다. -> 시간이 오래걸림 .. 성능 떨어진다.
소프트웨어 상식으로 알아두기~
방법2_ 인터럽트를 걸어서 thread 종료하는 방법
인터럽트 : 강제로 끼어드는 것을 의미
while문 계속 돌다가 인터럽트 만나면 빠져나감
인터럽트에 걸리려면 sleep을 줘야한다. 최소한의 sleep 1을 준다.
thread가 sleep일때만 인터럽트를 잡을 수 있다.
PrintMain2.java
PrintThread2.java
Console
방법3_ while문을 통해서 break
thread 종료
PrintThread3.java
PrintMain3.java
Console
데몬 스레드
일반적으로 스레드는 독립적으로 수행되기 때문에 메인 스레드를 종료해도 작업 스레드는 계속 실행된다.
그런데 어떤 스레드는 다른 스레드의 보조 작업을 수행하기 때문에 주된 스레드를 종료하면
더이상 존재할 이유가 없다. 이처럼 다른 스레드가 종료되면 자동으로 종료되어야하는 스레드를 데몬 스레드라고 하는데, 우선 순위가 가장 낮다.
DemonThread.java
DemonMain.java
Console
'IT > JAVA' 카테고리의 다른 글
[17일차] JAVA Programmers 개념정리 (0) | 2022.07.12 |
---|---|
[17일차] JAVA Generic / lambda (0) | 2022.07.12 |
[15일차] JAVA Programmers 개념정리 (0) | 2022.07.08 |
[15일차] JAVA (0) | 2022.07.08 |
[14일차] JAVA 객체지향 (0) | 2022.07.07 |
댓글