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.Foo대 new 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.