자바 : 오래된 것, 새로운 것
Java는 버전 7에 가까워지고 있습니다. 이전 버전의 Java를 기반으로하는 방법을 가르치는 방법을 가르치는 교과서와 교육 매뉴얼이 많이 있어야합니다.
최신 버전의 Java를 활용하기 위해 리팩토링을 수행하고있는 상용구 코드 상황, 특히 사람들이 습관을 통해 구현하는 것으로 보이는 상황은 무엇입니까?
열거 형. 교체
public static final int CLUBS = 0;
public static final int DIAMONDS = 1;
public static final int HEARTS = 2;
public static final int SPADES = 3;
와
public enum Suit {
CLUBS,
DIAMONDS,
HEARTS,
SPADES
}
Generics이며 컬렉션의 모든 요소를 통과하기 위해 더 이상 반복자를 만들 필요가 없습니다. 새 버전은 훨씬 더 좋고 사용하기 쉽고 이해하기 쉽습니다.
편집하다:
전에:
List l = someList;
Iterator i = l.getIterator();
while (i.hasNext()) {
MyObject o = (MyObject)i.next();
}
후
List<MyObject> l = someList;
for (MyObject o : l) {
//do something
}
유형의 지역 변수를 사용하여 StringBuffer
문자열 연결을 수행합니다. 동기화가 필요하지 않으면 StringBuilder
이 클래스가 더 나은 성능을 제공하기 때문에 대신 사용 하는 것이 좋습니다 (동기화되지 않았기 때문일 수 있음).
표준 입력에서 문자열 읽기 :
Java pre-5 :
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
reader.close();
}
catch (IOException e) {
System.err.println("error when closing input stream.");
}
자바 5 :
Scanner reader = new Scanner(System.in);
String str = reader.nextLine();
reader.close();
자바 6 :
Console reader = System.console();
String str = reader.readLine();
내가 본 것은 다음과 같습니다.
String.split()
대 StringTokenizer
.
StringTokenizer
새 코드에는 권장되지 않지만 여전히 사람들이 사용하는 것을 봅니다.
호환성과 관련하여 Sun은 Java가 이전 버전과 이전 버전과 호환되도록하기 위해 많은 노력을 기울이고 있습니다. 그것은 제네릭이 왜 그렇게 복잡한 지 부분적으로 설명합니다. 지원 중단은 또한 이전 코드에서 새 코드로 쉽게 전환하는 데 도움이됩니다.
Thread에 대한 다른 많은 대안 대신 Thread를 사용하는 이전 코드 ... 요즘에는 내가 실행하는 코드 중 원시 스레드를 사용해야하는 코드가 거의 없습니다. 추상화 수준, 특히 Callable / Futures / Executors 가 더 잘 제공됩니다 .
보다:
VARARGS도 유용 할 수 있습니다.
예를 들어 다음을 사용할 수 있습니다.
public int add(int... numbers){
int sum = 0 ;
for (int i : numbers){
sum+=i;
}
return sum ;
}
대신에:
public int add(int n1, int n2, int n3, int n4) ;
또는
public int add(List<Integer> numbers) ;
벡터 유형의 지역 변수를 사용하여 객체 목록을 보유합니다. 동기화가 필요하지 않은 경우에는이 클래스가 더 나은 성능을 제공하기 때문에 대신 ArrayList와 같은 List 구현을 사용하는 것이 좋습니다 (동기화되지 않았기 때문에).
포맷 된 인쇄는 JDK 1.5에서 도입되었습니다. 따라서 다음을 사용하는 대신 :
String str = "test " + intValue + " test " + doubleValue;
또는 StringBuilder를 사용하는 동등한 것,
하나는 사용할 수 있습니다
String str = String.format("test %d test %lg", intValue, doubleValue);
후자는 문자열 연결 및 문자열 작성기 버전 모두에서 훨씬 더 읽기 쉽습니다. 그래도 사람들이이 스타일을 매우 느리게 채택한다는 것을 알았습니다. 예를 들어 Log4j 프레임 워크는 이것을 사용하지 않지만 그렇게하는 것이 큰 이점이 될 것이라고 생각합니다.
Java 1.5부터 자동 박싱 / 언 박싱에 의해 자동으로 처리되는 기본 유형과 래퍼 유형 (예 : Integer에서 int로 또는 그 반대로) 간의 명시 적 변환.
예는
Integer myInteger = 6;
int myInt = myInteger.intValue();
간단히 다음과 같이 쓸 수 있습니다
Integer myInteger = 6;
int myInt = myInteger;
그러나 NullPointerExceptions를 조심하십시오 :)
Q1 : 글쎄요, 가장 명백한 상황은 제네릭 / 유형별 컬렉션입니다. 즉시 떠오르는 다른 하나는 개선 된 for 루프로, 훨씬 깔끔해 보이고 이해하기 쉽습니다.
Q2 : 일반적으로 고객 대면 앱용 애플리케이션과 함께 JVM을 번들링했습니다. 이를 통해 JVM 비 호환성에 대해 걱정할 필요없이 새로운 언어 기능을 사용할 수 있습니다.
JRE를 번들로 묶지 않았다면 호환성 이유로 1.4를 고수 할 것입니다.
1.5 이후의 간단한 변경이지만 JFrame의 contentPane에 액세스하는 Swing API에서 약간의 차이가 있습니다.
myframe.getContentPane().add(mycomponent);
된다
myframe.add(mycomponent);
물론 Enum의 도입은 과거에 상수를 사용했던 많은 응용 프로그램이 작동하는 방식을 변경했습니다.
String.format ()은 문자열 조작을 크게 향상 시켰으며 삼항 if 문은 코드를 읽기 쉽게 만드는 데 매우 유용합니다.
일반 컬렉션은 코딩을 훨씬 더 버그에 강하게 만듭니다. 낡은:
Vector stringVector = new Vector();
stringVector.add("hi");
stringVector.add(528); // oops!
stringVector.add(new Whatzit()); // Oh my, could spell trouble later on!
새로운:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("hello again");
stringList.add(new Whatzit()); // Won't compile!
반복자 사용 :
List list = getTheList();
Iterator iter = list.iterator()
while (iter.hasNext()) {
String s = (String) iter.next();
// .. do something
}
또는 때때로 보이는 다른 형태 :
List list = getTheList();
for (Iterator iter = list.iterator(); iter.hasNext();) {
String s = (String) iter.next();
// .. do something
}
이제 모두 다음으로 대체됩니다.
List<String> list = getTheList();
for (String s : list) {
// .. do something
}
정적 가져 오기는 쉽게 남용 될 수 있음을 인정하지만
import static Math.* ;
많은 수학 함수를 사용하는 클래스에서. 실제로 코드의 자세한 정도를 줄일 수 있습니다. 하지만 잘 알려지지 않은 라이브러리에는 권장하지 않습니다. 혼란을 일으킬 수 있기 때문입니다.
숫자를 문자열로 변환 :
String s = n + "";
이 경우에는 항상 더 나은 방법이 있다고 생각합니다.
String s = String.valueOf(n);
기존 어레이를 새 어레이로 복사 :
Java 5 이전 :
int[] src = new int[] {1, 2, 3, 4, 5};
int[] dest = new int[src.length];
System.arraycopy(src, 0, dest, 0, src.length);
자바 6 :
int[] src = new int[] {1, 2, 3, 4, 5};
int[] dest = Arrays.copyOf(src, src.length);
이전에는 명시 적으로 새 배열을 만든 다음 소스 요소를 새 배열에 복사해야했습니다 (매개 변수가 많은 메서드 호출). 이제 구문이 더 깨끗하고 새 배열이 메서드에서 반환되므로 만들 필요가 없습니다. 그건 그렇고, Arrays.copyOf 메서드 에는 Arrays.copyOfRange 라는 변형이 있는데 , 이는 소스 배열의 특정 영역을 복사합니다 ( System.arraycopy 와 매우 유사 함 ).
for
배열과 컬렉션을 반복 하는 새로운 -each 구조는 저에게 가장 큰 것입니다.
요즘 for
에는 인덱스 변수를 사용하여 배열을 하나씩 반복 하는 상용구 루프를 볼 때마다 비명을 지르고 싶습니다.
// AGGHHH!!!
int[] array = new int[] {0, 1, 2, 3, 4};
for (int i = 0; i < array.length; i++)
{
// Do something...
}
위의 내용을 for
Java 5에 도입 된 구성으로 대체합니다 .
// Nice and clean.
int[] array = new int[] {0, 1, 2, 3, 4};
for (int n : array)
{
// Do something...
}
Clean, concise, and best of all, it gives meaning to the code rather than showing how to do something.
Clearly, the code has meaning to iterate over the collection, rather than the old for
loop saying how to iterate over an array.
Furthermore, as each element is processed independent of other elements, it may allow for future optimizations for parallel processing without having to make changes to the code. (Just speculation, of course.)
Related to varargs; the utility method Arrays.asList() which, starting from Java 5, takes varargs parameters is immensely useful.
I often find myself simplifying something like
List<String> items = new ArrayList<String>();
items.add("one");
items.add("two");
items.add("three");
handleItems(items);
by using
handleItems(Arrays.asList("one", "two", "three"));
Annotations
I wonder no one mentioned it so far, but many frameworks rely on annotations, for example Spring and Hibernate. It is common today to deprecate xml configuration files are in favor of annotations in code (though this means losing flexibility in moving from configuration to meta-code, but is often the right choice).The best example is EJB 2 (and older) compared to EJB 3.0 and how programming EJB has been simplified thanks to annotations.
I find annotations also very useful in combination with some AOP tools like AspectJ or Spring AOP. Such combination can be very powerful.
Changing JUnit 3-style tests:
class Test extends TestCase {
public void testYadaYada() { ... }
}
to JUnit 4-style tests:
class Test {
@Test public void yadaYada() { ... }
}
Improved singleton patterns. Technically these are covered under the popular answer enums, but it's a significant subcategory.
public enum Singleton {
INSTANCE;
public void someMethod() {
...
}
}
is cleaner and safer than
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() {
...
}
public void someMethod() {
...
}
}
Converting classes to use generics, thereby avoiding situations with unnecessary casts.
Okay, now it's my turn to get yelled at.
I don't recommend 90% of these changes.
It's not that it's not a good idea to use them with new code, but breaking into existing code to change a for loop to a for(:) loop is simply a waste of time and a chance to break something. (IIWDFWI) If it works, don't fix it!
If you are at a real development company, that change now becomes something to code-review, test and possibly debug.
If someone doing this kind of a refactor for no reason caused a problem of ANY sort, I'd give them no end of shit.
On the other hand, if you're in the code and changing stuff on that line anyway, feel free to clean it up.
Also, all the suggestions in the name of "Performance" really need to learn about the laws of optimization. In two words, Don't! Ever! (Google the "Rules of optimization if you don't believe me).
I'm a little wary to refactor along these lines if that is all you are doing to your source tree. The examples so far do not seem like reasons alone to change any working code base, but maybe if you are adding new functionality you should take advantage of all the new stuff.
At the end of the day, these example are not really removing boiler plate code, they are just using the more manageable constructs of newer JDKs to make nice looking boiler plate code.
Most ways to make your code elegant are not in the JDK.
Using Swing's new DefaultRowSorter
to sort tables versus rolling your own from scratch.
New version of Java rarely break existing code, so just leave old code alone and focus on how the new feature makes your life easier.
If you just leave old code alone, then writing new code using new features isn't as scary.
String comparisons, really old school Java programmers I've met would do:
String s1 = "...", s2 = "...";
if (s1.intern() == s2.intern()) {
....
}
(Supposedly for performance reasons)
Whereas these days most people just do:
String s1 = "...", s2 = "...";
if (s1.equals(s2)) {
....
}
Using Vector instead of the new Collections.
Using classes instead of enums
public class Enum
{
public static final Enum FOO = new Enum();
public static final Enum BAR = new Enum();
}
Using Thread instead of the new java.util.concurrency package.
Using marker interfaces instead of annotations
It is worth noting that Java 5.0 has been out for five years now and there have only been minor changes since then. You would have to be working on very old code to be still refactoring it.
참고URL : https://stackoverflow.com/questions/258954/java-out-with-the-old-in-with-the-new
'IT Share you' 카테고리의 다른 글
현지화 된 문자열 Xcode 4… .strings 파일 복사 오류 유효성 검사 실패 (0) | 2020.11.15 |
---|---|
BroadcastReceiver가 BOOT_COMPLETED를 수신하지 않습니다. (0) | 2020.11.15 |
Java에서이 줄은 무엇을 의미합니까? boolean retry = id == 1; (0) | 2020.11.15 |
다차원 배열을 마샬링하는 방법 (0) | 2020.11.15 |
Spring MVC에서 ScrollableResults-backed Stream을 반환 유형으로 사용하는 데 문제가 있습니다. (0) | 2020.11.15 |