5.1 ๋น ๋ฅธ ์คํจ
๋ฌธ์ ์ฝ๋
class CruiseControl {
static final double SPEED_OF_LIGHT_KMH = 1079252850;
static final double SPEED_LIMIT = SPEED_OF_LIGHT_KMH;
private double targetSpeedKmh;
void setTargetSpeedKmh(double speedKmh) {
if (speedKmh < 0) {
throw new IllegalArgumentException();
} else if (speedKmh <= SPEED_LIMIT) {
targetSpeedKmh = speedKmh;
} else {
throw new IllegalArgumentException();
}
}
์ ์ฝ๋๋ else if์ ์ ์์ ์ธ ์คํ ํ๋ฆ์ ์ ๋ค๋ก ์์ธ ์ฒ๋ฆฌ ์กฐ๊ฑด์ด ๋ค์ด๊ฐ์์ด ์ ์์ ์ธ ์คํ ํ๋ฆ์ด ๋์ ๋์ง ์๋๋ค.
๋ํ, ๋ ๋ฒ์งธ ์กฐ๊ฑด์ !(speedKmh <= 0) && speedKmh <= SPEED_LIMIT ์ผ๋ก ํด์๋์ด์ผ ํ๊ณ
์ธ ๋ฒ์งธ ์กฐ๊ฑด์ !(๋๋ฒ์งธ์กฐ๊ฑด)์ผ๋ก ํด์๋์ด์ผ ํ๋ค.
์ด๋ฌํ ๊ณผ์ ์ JVM์๊ฒ๋ ๋ฌด์ฒ ๊ฐ๋จํ์ง๋ง ์ธ๊ฐ์๊ฒ๋ ๊ทธ๋ ์ง ์๋ค.
์ฝ๋๋ฅผ ๊ฐ์ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
๊ฐ์ ์ฝ๋
class CruiseControl {
static final double SPEED_OF_LIGHT_KMH = 1079252850;
static final double SPEED_LIMIT = SPEED_OF_LIGHT_KMH;
private double targetSpeedKmh;
void setTargetSpeedKmh(double speedKmh) {
// ๋งค๊ฐ๋ณ์ ๊ฒ์ฆ
if (speedKmh < 0 || speedKmh > SPEED_LIMIT) {
throw new IllegalArgumentException();
}
// ์ผ๋ฐ์ ์ธ ๊ฒฝ๋ก
targetSpeedKmh = speedKmh;
}
}
'๊ฒ์ฆ' ๊ณผ '์ ์์ ์ธ ๊ฒฝ๋ก'๋ฅผ ๋ถ๋ฆฌํจ.
'๊ฒ์ฆ'์ด ๋จผ์ ์คํ๋์ด ์์ธ ์ํฉ์ด๋ผ๋ฉด ๋น ๋ฅด๊ฒ ์คํจํ๋ค.
๊ทธ๋ฌ๋ฉด ์ด ํ์ ์ด์ด์ง๋ ํ๋ฆ์ '์ ์์ ์ธ ํ๋ฆ'์ด ๋๋ค.
5.2 ํญ์ ๊ฐ์ฅ ๊ตฌ์ฒด์ ์ธ ์์ธ ์ก๊ธฐ
๋ฌธ์ ์ฝ๋
class TransmissionParser {
static Transmission parse(String rawMessage) {
if (rawMessage != null
&& rawMessage.length() != Transmission.MESSAGE_LENGTH) {
throw new IllegalArgumentException("Bad message received!");
}
String rawId = rawMessage.substring(0, Transmission.ID_LENGTH);
String rawContent = rawMessage.substring(Transmission.ID_LENGTH);
try {
// rawId ๋ฌธ์์ด ์์ intํ์ผ๋ก ๋ฐ๊ฟ ์ ์๋ ๋ฌธ์๊ฐ ์์ ๋ ์ค๋ฅ๊ฐ ๋ฐ์!!
int id = Integer.parseInt(rawId);
String content = rawContent.trim();
return new Transmission(id, content);
} catch (Exception e) {
throw new IllegalArgumentException("Bad message received!");
}
}
}
์ ์ฝ๋๋ ์์ธ๋ฅผ 'Exception'์ผ๋ก ๋ฐ๊ณ ์๋ค. 'Exception'์ ์๋ฐ์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์์ธ ์ ํ์ด๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์ก๊ธธ ์ํ๋ ์์ธ ์ด์ธ์ NullPointerException๊ฐ์ ์ผ๋ฐ์ ์ธ ์ค๋ฅ๋ฅผ ์ก์ ์ ์๋ค.
์ฐ๋ฆฌ๋ ์ข ๋ ๊ตฌ์ฒด์ ์ธ ์์ธ๋ฅผ ์ก์ ์ ์๋๋ก ์ฝ๋๋ฅผ ๊ฐ์ ํด์ผ๋ง ํ๋ค.
๊ฐ์ ์ฝ๋
class TransmissionParser {
static Transmission parse(String rawMessage) {
if (rawMessage != null &&
rawMessage.length() != Transmission.MESSAGE_LENGTH) {
throw new IllegalArgumentException("Bad message received!");
}
String rawId = rawMessage.substring(0, Transmission.ID_LENGTH);
String rawContent = rawMessage.substring(Transmission.ID_LENGTH);
try {
// ์์ธ ๋ฐ์!!
int id = Integer.parseInt(rawId);
//
String content = rawContent.trim();
return new Transmission(id, content);
} catch (NumberFormatException e) { // ์์ธ ๊ตฌ์ฒดํ
throw new IllegalArgumentException("Bad message received!");
}
}
}
์ ์ฝ๋์์๋ parseInt์์ ์ซ์๊ฐ ์๋ ๊ฐ์ด ์์ ๋ ์์ธ๊ฐ ๋ฐ์ํ๋ฏ๋ก 'NumberFormatException'์ด ๋ฐ์ํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ catch ์กฐ๊ฑด์ ์ด๋ฅผ ์ถ๊ฐํด์ค๋ค. ---> ๊ฐ์ฅ ๊ตฌ์ฒด์ ์ธ ์์ธ๋ฅผ ์ก์!!
๋ง์ฝ ์ฌ๋ฌ ๊ฐ์ ์์ธ๋ฅผ ๋๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌํ๋ค๋ฉด ๋ค์ค ์บ์น ๋ฐฉ์์ ์ฌ์ฉํ์.
ex) catch(NumberFormatException | IOException)
5.3 ๋ฉ์์ง๋ก ์์ธ ์ค๋ช
์์ธ๋ฅผ ๊ตฌ์ฒดํํ๋ฉด ๋ฐ์ ํ์ ๋ง ๋ด๋ ๋ฌด์์ด ์๋ชป๋๋์ง ์์์ฑ ์ ์๋ค.
- ๋ฉ์๋์ ์๋ชป๋ ๋งค๊ฐ๋ณ์ ์ ๋ ฅ => IlleagalArgumentException ๋ฐ์
ํ์ง๋ง ์ฌ๊ธฐ๊น์ง๋ง ํ๋ฉด ์์ธ ๋ฐ์ ์ ํ ๋งฅ๋ฝ์ ์ ์๊ฐ ์๋ค.
์์ธ message๋ฅผ ์ข ๋ ์์ธํ๊ฒ ์ถ๊ฐํด ์์ธ ์์ฒด๋ก ๋งฅ๋ฝ์ ์ ์ ์๊ฒ ํด๋ณด์.
๊ฐ์ ์ฝ๋
class TransmissionParser {
static Transmission parse(String rawMessage) {
if (rawMessage != null
&& rawMessage.length() != Transmission.MESSAGE_LENGTH) {
throw new IllegalArgumentException(
// ๋ฉ์์ง ๊ตฌ์ฒดํ
String.format("Expected %d, but got %d characters in '%s'",
Transmission.MESSAGE_LENGTH, rawMessage.length(),
rawMessage));
}
String rawId = rawMessage.substring(0, Transmission.ID_LENGTH);
String rawContent = rawMessage.substring(Transmission.ID_LENGTH);
try {
int id = Integer.parseInt(rawId);
String content = rawContent.trim();
return new Transmission(id, content);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
// ๋ฉ์์ง ๊ตฌ์ฒดํ
String.format("Expected number, but got '%s' in '%s'",
rawId, rawMessage));
}
}
}
1. ์ ๋ณด๋ฅผ ๋๋ฝํ๊ฑฐ๋ ์ธ๋ชจ์๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ๋์ ๋ฐ๋ผ๋ ์ ๋ณด
2. ๋ฐ์ ๊ฒ
3. ์ ์ฒด ๋งฅ๋ฝ
์ด ์ธ๊ฐ์ง ์์๋ฅผ ๋ฉ์์ง๋ก ์ ๋ฌํ๋ฉด ๊ฐ๋ฐ์๋ ์์ธ์ ๊ทผ๋ณธ์ ์ด ์์ธ์ ๋ ๋นจ๋ฆฌ ์ถ์ ํ ์ ์๋ค.
5.4 ์์ธ ์ฌ์ฌ ๊นจ์ง ์๊ธฐ
์์ธ๋ ๋ ๋ค๋ฅธ ์์ธ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ค. ์ด๋ ๋ค์ ์์ธ๋ฅผ ๋์ ธ์ผํ๋ค.
์ด๋ฐ ๊ณผ์ ์ ํตํด ๊ฐ ์์ธ๊ฐ ๊ทธ ์์ธ๋ฅผ ์ผ์ผํจ ์์ธ์ ์ฐ๊ฒฐ๋ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์คํ ์ถ์ ์ ํ์ธํ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์์ธ ์ฌ์ฌ์ ๊นจ์ง ์๊ณ ์ ์งํ ์ ์์๊น?
class TransmissionParser {
static Transmission parse(String rawMessage) {
if (rawMessage != null
&& rawMessage.length() != Transmission.MESSAGE_LENGTH) {
throw new IllegalArgumentException(
String.format("Expected %d, but got %d characters in '%s'",
Transmission.MESSAGE_LENGTH, rawMessage.length(),
rawMessage));
}
String rawId = rawMessage.substring(0, Transmission.ID_LENGTH);
String rawContent = rawMessage.substring(Transmission.ID_LENGTH);
try {
int id = Integer.parseInt(rawId);
String content = rawContent.trim();
return new Transmission(id, content);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("Expected number, but got '%s' in '%s'",
rawId, rawMessage));
}
}
}
catch ๋ธ๋ก์์ ์์ธ๋ฅผ ๋์ง ๋ message์ ์ก์๋ ์์ธ๋ฅผ ์ฆ์ ์์ธ์ผ๋ก ์ ๋ฌํ๋๋ก ํ๋ค.
<EXAMPLE>
throw new IllegalArgumentException("Message", e);
5.5 ๋ณ์๋ก ์์ธ ๋ ธ์ถ
**์ด๋ ต๊ณ ์ดํด ์ ์๋จ**
๋ง์ถคํ ์์ธ๋ฅผ ๋ง๋ค์ด ๊ทธ ์์ธ๋ง์ ๋ฉ์์ง ํ๋๊ฐ ๋ค์ด๊ฐ ์์ธ ํด๋์ค๋ฅผ ์ ์ํ์ฌ ์ฌ์ฉํ๋ฉด ๋๋ค.
ํฅํ ์ด ํด๋์ค์ ํ๋๋ฅผ ์ฝ๊ฒ ์ถ์ถํ ์ ์๋ค.
5.6 ํ์ ๋ณํ ์ ์ ํญ์ ํ์ ๊ฒ์ฆํ๊ธฐ
Object signal = inputStream.readObject();
CrewMessage crewMessage = (CrewMessage) signal;
์ ์ฝ๋๋ ์คํธ๋ฆผ์ด ํญ์ CrewMessage ๊ฐ์ฒด๋ก ๋ค์ด์ฌ ๋๋ง ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๋ค.
๋ง์ฝ, ๊ทธ ์ธ์ ๊ฐ์ฒด๊ฐ ๋ค์ด์ค๊ฒ ๋๋ค๋ฉด ์คํธ๋ฆผ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์์ง๋ง cast ์์ธ๊ฐ ๋ฐ์ํ๊ฒ๋๋ค.
์ด๋ฌํ ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ์ฝ๋๋ฅผ ์์ ํด์ผํ๋ค.
Object signal = inputStream.readObject();
if (signal instanceof CrewMessage) {
CrewMessage crewMessage = (CrewMessage) signal;
}
'instanceof' ์ฐ์ฐ์๋ก ํ์ ์ ๊ฒ์ฆํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
๋ง์ฝ singnal์ ํ์ ์ด CrewMessage๋ฉด true๋ฅผ ๋ฐํํ๊ณ ๊ทธ ์ธ๋ false๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฒฐ๊ตญ, ์ฐธ์ผ๋๋ง ๋ฐํํ๊ธฐ ๋๋ฌธ์ ClassCastException์ด ๋ฐ์ํ์ง ์๋๋ค.
5.7 ํญ์ ์์ ๋ซ๊ธฐ
class Logbook {
static final Path LOG_FOLDER = Paths.get("/var/log");
static final String FILE_FILTER = "*.log";
List<Path> getLogs() throws IOException {
List<Path> result = new ArrayList<>();
DirectoryStream<Path> directoryStream =
Files.newDirectoryStream(LOG_FOLDER, FILE_FILTER);
for (Path logFile : directoryStream) {
result.add(logFile);
}
directoryStream.close();
return result;
}
}
DirectoryStream์ ์ด๊ณ close()๋ก ๋ซ๋ ํ๋์ ๋ณผ ์ ์๋ค. ๋ฌธ์ ๊ฐ ๋ฌด์์ผ๊น?
๋ฌธ์ ๋ ํ๋ก๊ทธ๋จ์ด ์์์ ์ฐ ํ close()๋ก ์์์ ํด์ ํ๊ธฐ ์ ์ ์์์ ์ฌ์ฉํ๋ค๊ฐ ์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ค. ์ด ๊ฒฝ์ฐ ์์ธ๋ก ์ธํด close()๊ฐ ์ ๋๋ก ์คํ๋์ง ์์ ์ ์๋ค.
--> '์์ ๋์ถ'์ด๋ผ ๋ถ๋ฆ
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ฌ์ฉํ๋ ์์์ ํญ์ ๋ซ์ ์ ์์๊น?
class Logbook {
static final Path LOG_FOLDER = Paths.get("/var/log");
static final String FILE_FILTER = "*.log";
List<Path> getLogs() throws IOException {
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> directoryStream =
Files.newDirectoryStream(LOG_FOLDER, FILE_FILTER)) {
for (Path logFile : directoryStream) {
result.add(logFile);
}
}
return result;
}
}
๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค. try ๋ฌธ ์์ ์์ ์ด๋ฉด๋๋ค.
์ด ๊ฒฝ์ฐ try ๋ฌธ์ด ์ข ๋ฃ๋๋ฉด ์๋ฐ๊ฐ ์์์ close()ํธ์ถ์ ์คํํ๋ค.
์ฌ์ค try, finally์์ finally ๋ถ๋ถ์์ close()๊ฐ ์คํ๋์ง๋ง ์ฐ๋ฆฌ๋ ์ปดํ์ผ๋ฌ๊ฐ ํด์ฃผ๋ฏ๋ก ๊ทธ๋ฅ try๋ฌธ๋ง ์ฌ์ฉํ๋๋ก ํ์.
5.8 ํญ์ ๋ค์ ์์ ๋ซ๊ธฐ
์ฌ๋ฌ ์์์ ๋์์ ์ฌ์ฉํ๋ฉด ์์ ๋ซ๊ธฐ๊ฐ ๋์ฑ ์ด๋ ต๋ค.
๊ฐ ์์๋ง๋ค ๋ชจ์ข ์ ์ด์ ๋ก ์คํจํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ค์ ์์์ ํญ์ ๋ซ๊ธฐ๊ฐ ์ฝ์ง์์ ๊ฒ์ด๋ค.
์ด๋ try-with-resources๋ฅผ ์ฌ์ฉํ๋ฉด ์ข๋ค.
์์์ try๋ฌธ ์์์ ์ด๊ธฐ๋ง ํ๋ฉด ์์์ ๊ฐ ์์์ ๋ซ์์ค๋ค.
์์์ ์ง์ ๊ด๋ฆฌํ์ง ๋ง๊ณ ๊ผญ try-with-resources ๋ธ๋ก ์์์ ์์์ ์ด์!
5.9 ๋น catch ๋ธ๋ก ์ค๋ช ํ๊ธฐ
try (DirectoryStream<Path> directoryStream =
Files.newDirectoryStream(LOG_FOLDER, FILE_FILTER)) {
for (Path logFile : directoryStream) {
result.add(logFile);
}
} catch (NotDirectoryException e) {
}
๋น catch ๋ธ๋ก์๋ ๋๋์ฒด ์ด๋ค ์๋๊ฐ ์จ์ด์์๊น??
List<Path> getLogs() throws IOException {
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> directoryStream =
Files.newDirectoryStream(LOG_FOLDER, FILE_FILTER)) {
for (Path logFile : directoryStream) {
result.add(logFile);
}
} catch (NotDirectoryException ignored) {
// No directory -> no logs!
}
return result;
}
์ถ๊ฐํ๋ฉด ์ข์ ๊ฒ
-> ๋น catch ์ธ ์ด์ ( ์ฃผ์ ์ค๋ช ์ถ๊ฐ)
-> ๋ช ์์ ์ผ๋ก ๋๋ฌ๋ด๊ธฐ (e -> ignored)
ignored๋ก ์์ธ๋ฅผ ๋ฌด์ํ๊ฒ ๋ค๊ณ ๋ช ์ํ๊ธฐ.
์ฃผ์์ผ๋ก ์ ์์ธ๋ฅผ ๋ฌด์ํ๋์ง ์ค๋ช ํ๊ธฐ.
5.10 5์ฅ์์ ๋ฐฐ์ด ๋ด์ฉ
์ด๋ค ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ์์ธ ์ฒ๋ฆฌ๋ ํ์์ด๋ค.
์์ธ๋ฅผ '์์ธ ์ฌ์ฌ'๋ก ์ฐ๊ฒฐํ์ง ์๊ฑฐ๋ '์์์ ๋ซ์ง ์๋ ๊ฒ' ๋ฑ์ ์ธ๋ถ์ ์ธ ์์์์ ์์ธ๊ฐ ์ฝ๊ฒ ๋ฐ์ํ๊ณ ์ค๋์ํ ์์๋ค.
ํ์ง๋ง, ์ด๋ฌํ ์ค์๋ฅผ ์ ์ง๋ฌ๋ ์ปดํ์ผ์ ๋๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ฅผ ๋์ค์ ์๊ฒ ๋๊ณ ์ถ์ ํ๊ธฐ๋ ๋์ฑ ์ด๋ ค์์ง๋ค.
5์ฅ์์๋ ํ์ผ ์ฒ๋ฆฌ๋ ๋คํธ์ํน ์ฒ๋ผ ๋ถ๊ฐํผํ๊ฒ ์ ์ดํ ์ ์๋ ๋ถ๋ถ๋ค์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋ค.
6์ฅ์์๋ ํ๋ก๊ทธ๋จ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ธฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด ์๋ํ๋ ๊ฐ์ฅ ์ค์ํ ๋๊ตฌ์ธ '๋จ์ ํ ์คํธ'์ ๋ํด ํ์ตํ๋ค.
'๐์ฝ์ ์ฑ ์ ๋ฆฌ > ์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 7์ฅ : ๊ฐ์ฒด ๋์์ธ (0) | 2021.04.15 |
---|---|
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 6์ฅ : ์ฌ๋ฐ๋ฅด๊ฒ ๋๋ฌ๋ด๊ธฐ (0) | 2021.04.15 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 4์ฅ : ์ฌ๋ฐ๋ฅด๊ฒ ๋ช ๋ช ํ๊ธฐ (0) | 2021.04.13 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 3์ฅ : ์ฌ๊ธฐ๋กญ๊ฒ ์ฃผ์ ์ฌ์ฉํ๊ธฐ (0) | 2021.04.09 |
[์๋ฐ ์ฝ๋ฉ์ ๊ธฐ์ ] 2์ฅ : ์ฝ๋ ์คํ์ผ ๋ ๋ฒจ์ (0) | 2021.04.07 |