Java를 배우는 C # 개발자가 간과 할 수있는 가장 큰 차이점은 무엇입니까? [닫은]


87

Java를 배우려는 C # 개발자의 경우 두 언어 사이에 지적해야 할 큰 차이점이 있습니까?

어떤 사람들은 사물이 똑같다고 생각할 수 있지만 간과해서는 안되는 수입 측면이 있습니까? (또는 당신은 정말로 망칠 수 있습니다!)

OOP 구성, GC 작동 방식, 참조, 배포 관련 등의 측면에서 볼 수 있습니다.




또한 가능성이 우리 자신의 "C 번호의 숨겨진 기능"이다 간과 할 stackoverflow.com/questions/9033/hidden-features-of-c
존 K

답변:


122

내 머리 꼭대기에서 몇 가지 문제가 있습니다.

  • Java에는 사용자 정의 값 유형 (구조체)이 없으므로 찾아 보지 마십시오.
  • Java 열거 형은 C #의 "명명 된 번호"접근 방식과 매우 다릅니다. 더 OO입니다. 조심하면 큰 효과를 낼 수 있습니다.
  • byte Java로 로그인되어 있습니다 (불행히도).
  • C #에서 인스턴스 변수 이니셜 라이저 는 기본 클래스 생성자 보다 먼저 실행됩니다 . Java에서는 실행 된 후에 실행됩니다 (예 : "this"클래스의 생성자 본문 바로 앞).
  • C #에서 메서드는 기본적으로 봉인됩니다. Java에서는 기본적으로 가상입니다.
  • C #의 기본 액세스 한정자는 항상 "현재 컨텍스트에서 사용할 수있는 가장 제한적인 액세스"입니다. Java에서는 "패키지"액세스입니다. (Java의 특정 액세스 수정 자에 대해 읽어 볼 가치가 있습니다.)
  • Java 및 C #의 중첩 유형은 약간 다르게 작동합니다. 특히 액세스 제한이 다르며 중첩 유형을 선언하지 않는 한 static포함하는 클래스의 인스턴스에 대한 암시 적 참조를 갖게됩니다.

5
+1 이것은 초보자를위한 훌륭한 목록입니다.
Jim Schubert

3
@Jon Skeet : +1, Java 7까지 Lambda와 LINQ를 놓칠 수 있습니까?
Kb.

1
"C #에서 인스턴스 변수 이니셜 라이저는 기본 클래스 생성자보다 먼저 실행됩니다. Java에서는 실행 된 후에 실행됩니다 (예 :"this "클래스의 생성자 본문 바로 앞)."-Eeer, 자세히 설명해 주시겠습니까? 확실하지 난 정말 당신이 :) 무슨 말을하는지 이해
cwap

7
@cwap : C #에서 실행 순서는 "인스턴스 변수 이니셜 라이저, 기본 클래스 생성자, 생성자 본문"입니다. Java에서는 "수퍼 클래스 생성자, 인스턴스 변수 이니셜 라이저, 생성자 본문"입니다. (인스턴스 변수 이니셜 라이저는 선언 시점에서 인스턴스 변수에 값을 할당 할 때 얻는 것입니다.)
Jon Skeet

1
@cwap : 예, 그게 제가 의미하는 바입니다. 후자는 객체 이니셜 라이저입니다.
Jon Skeet


17

아무도 속성에 대해 언급하지 않았다는 사실에 놀랐습니다. C #에서는 매우 근본적이지만 Java에는 없습니다. C # 3 이상에서는 속성도 자동으로 구현되었습니다. Java에서는 GetX / SetX 유형 메소드를 사용해야합니다.

또 다른 명백한 차이점은 Java에는없는 C # 3의 LINQ 및 람다 식입니다.

축어 문자열 (@ ""), 연산자 오버로딩, 수율을 사용하는 반복기 및 사전 프로세서와 같이 Java에서 누락 된 몇 가지 간단하지만 유용한 것들이 Java에서도 누락되었습니다.

C #에서 개인적으로 가장 좋아하는 것 중 하나는 네임 스페이스 이름이 실제 디렉터리 구조를 따를 필요가 없다는 것입니다. 이 유연성이 정말 마음에 듭니다.


10

많은 차이점이 있지만 다음과 같은 점이 생각납니다.

  • Java에서 연산자 오버로딩이 없습니다. instance.Equals (instance2) 대 instance == instance2 (특히 문자열 포함)를 확인하십시오.
  • I 접두사가없는 인터페이스에 익숙해 지십시오. 종종 Impl 접미사가 붙은 네임 스페이스 나 클래스를 볼 수 있습니다.
  • Java 메모리 모델로 인해 이중 확인 잠금이 작동하지 않습니다.
  • 클래스 이름을 접두사로 붙이지 않고 정적 메서드를 가져올 수 있으며, 이는 특정 경우 (DSL)에서 매우 유용합니다.
  • Java의 Switch 문에는 기본값이 필요하지 않으며 문자열을 케이스 레이블 (IIRC)로 사용할 수 없습니다.
  • 자바 제네릭은 당신을 화나게 할 것입니다. Java 제네릭은 런타임에 존재하지 않으며 (적어도 1.5에서는) 컴파일러 트릭이므로 제네릭 유형에 대한 리플렉션을 수행하려는 경우 문제가 발생합니다.

4
마지막으로 확인한 결과 문자열이 == 오버로드되지 않았으며 Java 7에도 추가된다는 소식을 듣지 못했습니다. 그러나 문자열 연결을 위해 + 오버로드를 수행합니다.
Michael Madsen

3
예, 문자열을 ==와 비교하는 것은 초보자에게 매우 일반적인 함정입니다. .equals당신이 사용해야하는 것입니다.
Michael Myers

또한 정적 메서드에 대한 주석을 이해하지 못합니다. 거의 모든 언어가 정적 메서드 또는 이와 동등한 것을 허용하지 않습니까?
Michael Myers

나는 거의 찬성했지만 제네릭에 대해서는 동의하지 않습니다. 나는 유형 삭제를 좋아한다.
finnw

2
"Java의 스위치 문에는 기본값이 필요하지 않습니다."-C #도 마찬가지입니다.
RenniePet 2013-07-12

8

.NET은 제네릭을 수정했습니다. Java는 제네릭을 지 웠습니다.

차이점은 다음과 같습니다. ArrayList<String>객체 가있는 경우 .NET에서는 객체에 type이 있음을 (런타임에) 알 수있는 ArrayList<String>반면, Java에서는 런타임에 객체가 유형입니다 ArrayList. String부분은 손실됩니다. 비 String객체를에 넣는 경우 ArrayList시스템은이를 적용 할 수 없으며 항목을 추출하려고 시도한 후에 만 ​​알 수 있으며 캐스트가 실패합니다.


1
... 어딘가에String 확인되지 않은 캐스트를 만들지 않고는 해당 목록 에 비 객체를 넣을 수 없다는 점을 추가 할 가치가 있지만 컴파일러는 해당 시점에서 컴파일러가 더 이상 제네릭 경계를 확인할 수 없다고 올바르게 경고합니다. 목록이 항상 의 변수에 저장되어있는 한 문자열이 아닌 객체를 삽입하려는 시도는 컴파일되지 않습니다. List<String>
Andrzej Doyle

"문자열이 아닌 객체를 ArrayList에 넣으면 시스템이이를 적용 할 수 없습니다.": 시스템 컴파일 타임에이를 적용합니다. 그러나 캐스팅 (또는 제네릭을 사용하지 않음)을 통해이를 피할 수 있습니다. 그런 다음 런타임 검사가이를 포착하지만 추출 할 때만 가능합니다.
sleske 2010 년

1
@Andrzej, @sleske : 저는 런타임에 대해서만 이야기하고 있습니다. 리플렉션을 통해 객체를 얻고 add메서드를 호출한다고 가정 해 보겠습니다 (다시 리플렉션을 통해). 시스템은 비 String객체를 즉시 거부 get합니까? 아니면 결과를 캐스팅 할 때만 거부 합니까?
Chris Jester-Young

@sleske :하지만 IIRC에서는 유형 검사를 우회하기 위해 암시 적 캐스트 만 필요합니다.
Niki

@Judah : 유형의 객체를 가질 수 없기 때문에 변경 사항을 롤백했습니다 (예, 사실 1 년 후) List. List, like ArrayList및의 내림차순 유형의 객체를 가질 수 있습니다 LinkedList. (사용하는 것이 중요합니다List 대신 ArrayList주변을 통과 할 때, 그러나 당신이 말할 수 없다는 사실을 변경하지 않습니다 new List().)
크리스 광대 - 젊은

6

Java의 C #에서 내가 놓친 한 가지는 확인 된 예외를 강제로 처리하는 것입니다. C #에서는 메서드가 던질 수있는 예외를 인식하지 못하고 문서화 또는 테스트를 통해이를 발견하는 것이 일반적입니다. 확인 된 예외가있는 Java에서는 그렇지 않습니다.


1
FWIW, 이것은 C #의 개발에서 고려되었으며 그것들을 제외하는 이유는 실제입니다. artima.com/intv/handcuffs.html을 고려 하십시오 . 디자이너가 체크 된 예외에 대해 철학적으로 반대하는 것이 아니라, 모든 털이 많은 단점없이 유사한 이점을 제공하는 더 나은 기술을 기다리고 있습니다.
Greg D

예, 예, 매우 논쟁의 여지가있는 주제입니다 ...
sleske 2010-01-06

2
나는 C #에 예외를 확인하지 않았다는 사실이 마음에 들지만, 이것이 차이점을 지적하는 첫 번째 게시물이므로 +1.
Nick

5

Java는 값 유형이 아닌 기본 요소에 대한 자동 박싱 기능을 제공하므로 System.Int32[]C #의 값 배열 이지만 객체 Integer[]에 대한 참조 배열이므로 Integer고성능 계산에 적합하지 않습니다.


1
Pete : 그것은 훌륭한 점이며, 제가 알지 못했거나 적어도 고려하지 않은 점입니다 (C # 개발자이고 Java를 처음 사용하는 것).
Jim Schubert

4

델리게이트 나 이벤트가 없습니다-인터페이스를 사용해야합니다. 다행히도 클래스와 인터페이스 구현을 인라인으로 만들 수 있으므로 큰 문제는 아닙니다.


3
"그렇게 큰 문제가 아닙니다". 권리. 왜냐하면 x => x.Foonew Bar() { public void M(SomeType x) { return x.Foo; } }-누가 코드가 10 배 더 짧아지는 것에 관심이 있습니까?
Kirk Woll

2

Java에 내장 된 날짜 / 달력 기능은 System.DateTime에 비해 끔찍합니다. 여기에 많은 정보가 있습니다. Java Date & Time API의 문제점은 무엇입니까?

이 중 일부는 C # 개발자에게 문제가 될 수 있습니다.

  • Java Date 클래스는 변경 가능하므로 날짜를 반환하고 전달할 수 있습니다.
  • 대부분의 java.util.Date 생성자는 더 이상 사용되지 않습니다. 단순히 날짜를 인스턴스화하는 것은 매우 장황합니다.
  • 웹 서비스와 잘 상호 운용되는 java.util.Date 클래스를 얻은 적이 없습니다. 대부분의 경우 양쪽의 날짜는 다른 날짜 및 시간으로 크게 변형되었습니다.

또한 Java에는 GAC 및 강력한 이름의 어셈블리가 제공하는 것과 동일한 기능이 모두 포함되어 있지 않습니다. Jar Hell 은 외부 라이브러리를 링크 / 참조 할 때 잘못 될 수있는 용어입니다.

패키징 / 배포에 관한 한 :

  • 실제로 여러 다른 애플리케이션 서버 (Glassfish, Websphere 등)에서 설치하고 실행하는 EAR / WAR 형식으로 웹 애플리케이션을 패키지화하는 것은 어려울 수 있습니다.
  • Java 앱을 Windows 서비스로 배포하려면 C #보다 훨씬 더 많은 노력이 필요합니다. 이에 대해 제가받은 대부분의 권장 사항은 무료가 아닌 타사 라이브러리와 관련이 있습니다.
  • 애플리케이션 구성은 프로젝트에 app.config 파일을 포함하는 것만 큼 쉽지 않습니다. java.util.Properties 클래스가 있지만 강력하지 않으며 .properties 파일을 놓을 올바른 위치를 찾는 것이 혼란 스러울 수 있습니다.

1

Java에는 대리인이 없습니다. 따라서 참석자가 테이블에 가져다주는 모든 이점을 제외하고 이벤트도 다르게 작동합니다. 단순히 메서드를 연결하는 대신 인터페이스를 구현하고 대신 연결해야합니다.


1

내 인터뷰 목록에있는 b / c에서 튀어 나온 한 가지는 Java에 메소드 숨김을위한 "새로운"키워드 아날로그가 없으며 "여기에 새로 넣어야합니다"라는 컴파일러 경고가 없다는 것입니다. 재정의하려는 경우 실수로 메서드를 숨기면 버그가 발생합니다.

(예를 들어 편집) 예, B는 A에서 파생됩니다 (C # 구문을 사용하면 Java는 마지막으로 확인한 것과 동일한 방식으로 작동하지만 컴파일러 경고를 표시하지 않습니다). A의 foo 또는 B의 foo가 호출됩니까? (A가 호출됩니다. B를 구현 한 개발자를 놀라게 할 것입니다.)

class A 
{
public void foo() {code}
}

class B:A
{
public void foo() {code}
}    

void SomeMethod()
{
A a = new B(); // variable's type is declared as A, but assigned to an object of B.
a.foo();
}

2
Java에서 실수로 인스턴스 메소드를 숨기는 방법은 무엇입니까? 그것들은 최종적입니다-그래서 new의도적으로 숨기는 재정의 또는 방법이 없습니다 -또는 최종적이지 않기 때문에 숨겨지기보다는 재정의됩니다.
Pete Kirkham

추가 된 예. 한동안 Java에서 테스트하지 않았지만 인터뷰 질문은 원래 이전 회사의 Java 그룹에서 나왔습니다. C #에서 컴파일러 경고는 일반적으로 사람들이 이름을 변경 함을 의미합니다. 나는 그것이 매우 이상한 경우임을 인정하지만, OP는 언어를 바꿀 때 문제를 찾기가 어려울 수있는 것들을 요구하는 것 같았다.
Jim L

1
여기서 차이점은 Java에서는 모든 메소드가 가상이라는 것입니다 (Java에서는 항상 동적 메소드 디스패치를 ​​수행하기 때문에 호출되는 B.foo ()가 됨). 반면 C #에서는 기본적으로 가상이 아닙니다 (A.foo ()가 호출됩니다). Java 용 코딩 스타일 검사기는 B가 @Override 주석을 사용해야한다고 알려줍니다.
William Billingsley

1

Java에는 LINQ가 없으며 문서는 지옥입니다. Java의 사용자 인터페이스는 개발하기 어렵고 Microsoft가 제공 한 모든 좋은 기능 (WPF, WCF 등)을 잃게되지만 사용하기 어렵고 거의 문서화되지 않은 "API"가됩니다.


0

C #에서 오는 Java로 작업 할 때 지금까지 겪은 한 가지 문제는 예외와 오류가 다릅니다.

예를 들어 catch (Exception e)를 사용하여 메모리 부족 오류를 포착 할 수 없습니다.

자세한 내용은 다음을 참조하십시오.

왜 java-lang-outofmemoryerror-java-heap-space-not-caught


이것은 의도적으로 잡기에서 응용 프로그램 프로그래머를 억제하는 그런 식으로 설계
finnw

그래, 나는 그것이 확신하지만, 예외를 잡기에 대해 :) 루프 나를 던졌다, 당신은 걱정할 필요가 모든 C #을 측면에서 오는
크리스 Persichetti

0

Java를 사용한 지 너무 오래되었지만 응용 프로그램 개발에서 즉시 눈에 띄는 것은 C # 이벤트 모델, C # 드래그 앤 드롭 vs Swing에서 레이아웃 관리자 사용 (앱 개발을 수행하는 경우) 및 예외 처리였습니다. Java는 예외를 포착하고 C #이 필요하지 않은지 확인합니다.


0

제목에 대한 직접적인 질문에 대한 답변 :

"Java를 배우는 C # 개발자, 간과 할 수있는 가장 큰 차이점은 무엇입니까?"

A : Java가 Windows에서 상당히 느리다는 사실.


4
저는 OpenSuSE 64 비트와 Windows 7 64 비트를 실행하고 있으며, Eclipse IDE는 Windows에서 더 빠릅니다. 귀하의 답변은 개인적인 관찰을 기반으로합니까, 아니면 실제 벤치 마크를 기반으로합니까?
Jim Schubert

0

Java로 전환 할 때 가장 괴롭히는 차이점은 문자열 선언입니다.

stringJava의 C # (대부분)String

그것은 매우 간단하지만 나를 믿으십시오. s하지 않는 습관이있을 때 너무 많은 시간을 낭비하게 만듭니다 S!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.