IT 이모저모

자바 9 개선점 - 2

exien 2018. 3. 30. 14:57

try-with-resources 문장의 개선

 try-with-resources 문장은 반드시 닫아야한다 자원 문장의 끝이 반드시 닫히도록하기위한 구문입니다.

 이 구문을 사용하지 않거나 Java 7 이하의 코드가 될 수있는 분은 finally로 close () 메소드를 실행해야했을 것입니다. 그러나 Java 7에서이 구문이 도입 된 위해 finally에서의 설명이 필요 없어지고, 그리고 Java 9는보다 직관적으로 설명 할 수있게되었습니다. 실제로 Java 7 이전과 Java 7 이상, 그리고 Java 9에서 설명 할 수있는 방법을 나타낸 것이 Listing 7입니다.

목록 7 try-with-resources 사용 예 (src / main / com / coltware / part6 / jep213 / TryWithResource.java 발췌)
// (1) Java 7 이전 SampleReader r1 = new SampleReader (); try { 
  r1 . read (); } catch ( Exception ex ) { 
  r1 . delete (); } finally { try { 
    r1 . close (); } catch ( Exception ex ) { } }
  




 
   
  
  
  


// (2) Java 7 이상 try ( SampleReader r7 = new SampleReader ()) { 
  r7 . read (); } catch ( Exception ex ) { // r7.delete (); 실행할 수없는 }
  


  


// (3) Java 9 이상 SampleReader r9 = new SampleReader (); try ( r9 ) { 
  r9 . read (); } catch ( Exception ex ) { 
  r9 . delete (); }
  





public class SampleReader implements AutoCloseable { public void read () { throw new RuntimeException ( "error" ); } // 오류가 발생한 경우에만 수행 할 처리 public void delete () { System . err . println ( "delete () " ); } @Override public void close () throws IOException { System . err . println ( "close () "    
   
      
  
  
    
    
  
  
      
    ); } }
  

 이번 예제에서는 간단한 SampleReader라는 AutoCloseable 인터페이스를 구현 한 클래스를 사용하여 확인합니다. 이 클래스에서는 문제가 알기 쉽도록 read 메소드는 반드시 오류가 발생하게됩니다.

 (1)는 Java 7 이전의 기술 방법에 오류가 발생해도 반드시 수행 할 수 있도록 finally에 close 메소드에서 실행했습니다. 이 설명을하지 않으면 close 메소드가 호출되지 않기 때문에 자원을 제대로 확보 할 수 없습니다.

 (2)는 Java 7에서 설명하는 방법입니다. try 문에서 선언 한 자원 만 자동으로 close되는 대상입니다. 그러나 이것으로는 try 문의 범위 밖에서는 사용할 수 없기 때문에 예를 들어, catch 및 finally에서 특별히 다른 작업을하고 싶어도 사용할 수 없습니다. 이번 샘플과 같이 오류가 발생했을 경우, delete () 메소드를 실행하고 싶어도 범위 외이기 때문에 설명 할 수 없습니다.

 그래서 Java 9에서 (3)과 같이 변수 선언을 try 문의 범위 밖에서 선언하고도 try 문으로 리소스를 지정하면 자동으로 리소스를 해제주게되었습니다.

Java 기반 모듈에서 사용할 수있는 Logger

 Java에는 이미 java.util.logging라는 패키지가 로그에 대해서는 이쪽에서 구현되어 있습니다. 는 이번 새로 마련된 System.Logger 은 어떤 차이가 있을까요?

 예를 들어, SLF4J 등을 사용하는 사람에게 알기 쉽다고 생각합니다. SLF4J는 로그의 구체적인 구현을 제공하고 있지 않기 때문에 어떤 로그 구현을 사용하더라도 로그를 출력하는 측의 프로그램에서 같이 작성할 수 있습니다.

 구체적인 로그 출력을위한 구현에 무엇을 사용 하는가는 실행시에 결정할 수 있습니다. System.Logger, JDK 표준 로깅을위한 인터페이스입니다. 기존의 타사 라이브러리도 향후이기구를 사용해 구현되도록되어 간다고 생각합니다.

 실제로 로그를 작성할 때 코드를 나타낸 것이 Listing 8입니다.

목록 8 로그를 출력하는 측 코드 예제 (src / main / com / coltware / part6 / jep264 / SystemLog.java 발췌)
System . Logger logger = System . getLogger ( "logname" ); 
logger . log ( System . Logger . Level . INFO , "system log" ); 

// 다음 출력 예 // 2 월 17, 2018 1:36:39 오후 com.coltware.part6.jep264.SystemLog check // 정보 : system log

 로그 출력을위한 구현 서비스기구를 사용하여 제공해야하지만 특히 아무것도 지정하지 않은 경우 java.util.logging API를 사용할 수 있습니다.

 직접 로깅 구현을 제공하는 데 필요한 코드를 나타낸 것이 목록 9입니다.

목록 9 로그 구현을 지정하는 경우의 예 (src / main / com / coltware / part6 / jep264 / SystemLoggerFinder.java 발췌)
// (1) 사용하는 로그 클래스를 지정하는 클래스를 만들 public class SampleLoggerFinder extends System . LoggerFinder { @Override public System . Logger getLogger ( String name , Module module ) { return new SampleLogger ( name ); } }
     
    
        
          
    


// (2) module-info.java에서 만든 클래스를 서비스로 사용할 수 있도록 지정 
uses System . LoggerFinder ; 
provides System . LoggerFinder with SampleLoggerFinder ;  

 (1)에서는 System.LoggerFinder 클래스를 상속 한 클래스를 만들고 그 속에서 자신이 만든 또는 외부 라이브러리 등 System.Logger 인터페이스를 구현 한 클래스를 반환하도록 지정합니다.

 이어 서비스로 클래스를 사용할 수 있도록 module-info.java에서 System.LoggerFinder을 이용하는 선언과 그 System.LoggerFinder의 구현으로 SampleLoggerFinder을 이용하는 선언을합니다.

기타 주목할만한 개선

 여기에서 다른 주목할만한 개선점을 설명합니다.

 먼저 속성 파일 (ResourceBundle)로 UTF-8 등의 문자 코드로 기술 할 수이 변경 모두 기본 파일 인코딩이 ISO-8859-1에서 UTF-8로 변경되었습니다. 이 문제는 이미 프레임 워크 등을 사용하는 사람은 그 프레임 워크에서 개별 대책을 취하고있는 경우도 있지만, 기본적으로 문제없이 사용할 수 있습니다.

 또한, 그 이외로는 String 내부 데이터 보존 형식이 바뀌 었습니다. 지금까지는 1 문자 당 2byte 데이터를 관리하고 있었지만 Latin-1과 같이 1byte로 관리 할 수있는 코드 만의 경우에는 1byte로 관리하도록되어 있습니다. 이것은 정상적인 이용이 1byte 관리에 문제 없다는 것이 큰 이유입니다. 그러나 API로 작동에 영향을주지 않으므로 지금까지의 코드에 영향을주지 않습니다. 또한, 일본어 데이터 같은 경우에는 같이 2byte로 관리됩니다.

 세세한 부분에서의 메모리 사용량 개선은 개발자에게는 그다지 크지 않은 변경이라고도 할 수 있지만 하드웨어 나 OS에 최적화 또는 메모리 효율 개선 흐름은 Java10 이후의 "Project Valhalla"와 " Project Panama "라는 프로젝트에서보다 본격적인 개선이 진행될 예정입니다. 그런 흐름을 알 하나의 주제로 이번 String 내부의 개선을 파악하면 좋을 것입니다.

마지막으로

 본 연재에서는 제 2 회 이후 Java 코딩을 중심으로 Java 9의 변경 사항에 대해 소개했습니다. 모듈 기능이라는 큰 추가 요소에 주목하기 쉽지만, 잘게 기존 부분의 개선도 이루어지고있는 것을 알 수 있습니다.

 다음은 Java 실행 환경면에서의 변화이며, jlink 명령과 Multi-Release Jar 파일을 중심으로 소개합니다. 또한 굳이 주관적인 관점에서 필자가 느끼는 Java에 대한 현재의 흐름과 향후 대해 설명 할 예정입니다.