0

함수에 매개 변수로 인스턴스를 전달하는 경우가 종종 있습니다. 대신 객체의 매개 변수를 전달하고 메소드 내에서 초기화하는 것도 마찬가지로 가능했습니다.인스턴스를 메서드에 전달합니다. 전달 매개 변수

예 :

class MyCanvas extends JComponent { 

    private static final long serialVersionUID = 1L; 

    private static ArrayList<String> textData; 
    private static ArrayList<Rectangle> rectData; 

    @Override 

    public void paintComponent(Graphics g) { 

     if(g instanceof Graphics2D){ 

      //Draw the rectangles and text 
     } 
    } 

    public void addText(int x, int y, String text){ 
     textData.add(text); 
    } 

    //Do this: 
    public void addRect(Rectangle rect){ 
     rectData.add(rect); 
    } 

    //Or do this? 
    public void addRect(int x, int y, int z, int q){ 
     rectData.add(new Rectangle(x, y, z, q); 
    } 

} 

이 경우, 가변성을 감소 네 개의 정수를 전달. 이론적으로는 취약점의 잠재력과 함께 오류 표면적을 줄여야합니다.

JVM은 어떻게이 두 예제를 다르게 처리합니까?

진정한 오류/취약성이 적은가요?

성능 측면에서 다른 것보다 효율적입니까?

참고 : 이것은 디자인 환경 설정에 대한 질문이 아닙니다. 두 가지 방법으로 유연하고 효율적인 방법으로 매개 변수를 여러 방법으로 묶거나 바인딩 할 수 있습니다. 내가 알고 싶은 것은 바이트 코드 레벨에서의 차이점과 바이트 코드 레벨에서 분명히 더 효율적/안전한지 여부입니다.

+0

"또는 매개 변수를 전달하고 메서드에서 초기화 하시겠습니까?" 'Frobnitz'를 만들기 위해 여러 매개 변수를 사용한다면'Frobnitz' 인스턴스를 대신 전달하십시오. 이는 'Frobnitz'의 특정 구현에 대한 올바른 결합을 감소시킵니다. 'MockFrobnitz'를 통과 시키면 테스트하기가 더 쉽습니다. –

+0

또한, 함수에 전달 된 후 객체의 변경이 걱정되는 경우, 메소드 내부에서 복제를 사용할 수 있습니다. –

+0

또는 [facade] (https://en.wikipedia.org/wiki/Facade_pattern)에 인스턴스를 래핑하면 다른 사람들이 사용하기를 원하는 방법 만 공개 할 수 있습니다. –

답변

1

API 디자인 관점에서 Rectangle (또는 Shape)을 전달하는 것이 좋습니다. 하나의 의미에서, 모서리와 치수를 지정하는 것은 구현입니다. 다른 구현은 반대 구석을 지정합니다. 모양을 전달하면 코드를보다 쉽게 ​​적용 할 수 있습니다.

여기에서 주된 문제는 Rectangle의 변경 가능성 때문입니다. 이것에 대한 효율성 논쟁이 있지만, 만약 그것이 설계 되었다면 Shape이 변경 가능할 지 궁금합니다. 많은 응용 프로그램에서 불변의 데이터 형식은 많은 이점을 제공하며 데이터의 안전한 공유가 그 중 하나입니다.

MyCanvas을 구현 중이므로 Rectangle 인스턴스가 수정되지 않았으므로 "안전"하다고 자신 할 수 있습니다. 그러나 다른 사람이 발신자를 쓰고 있고 MyCanvas이 완전히 신뢰하지 못하는 블랙 박스 일 경우 도움이되는 두 가지가 있습니다.

먼저 모양이 수정되지 않도록 지정하여 도형을 허용하는 MyCanvas 메서드를 문서화 할 수 있습니다. Java의 경우,이 스펙은 메소드와 클래스에 대해 Javadoc comments에 위치해야합니다.이는 일반적인 관행입니다. 신뢰할 수없는 작성자가 작성한 에이전트를 실행할 수있는 플러그인 시스템을 작성하지 않는 경우 프로그래머는 일반적으로 API에서 contract,이라는 약정을 사용합니다.

두 번째로 호출자가 해당 보증을받지 못하면 "Rectangle"인스턴스를 임시 복사본에 복사하고 복사본을 전달할 수 있습니다. 메서드가 반환 된 후 그들은 결코 Rectangle의 상태를 읽지 않으므로, 당신이 그 일을하는 것이 중요하지 않습니다. Rectangle이 변경 가능하기 때문에 상당히 효율적으로 수행 할 수 있습니다.


바이트 코드 관점에서 보면 Rectangle을 전달하는 것이 더 빠릅니다. 통과 된 각 매개 변수에 대해 별도의 명령이 실행됩니다. 더 많은 매개 변수, 자세한 지침. 또한 Rectangle을 전달하면 호출자의 인스턴스를 다시 사용할 수 있으며 원시 요소를 전달하는 데 불필요한 Rectangle을 새로 할당해야합니다.

"네 개의 정수를 전달하면이 경우 변동성이 줄어 듭니다. 이론적으로 말하자면 오류 표면적은 취약점 가능성과 함께 감소해야합니다."

나는 현실, 실제 세계에서 네 int 매개 변수와 같은 동일한 유형의 여러 인수와 방법, 매우 오류가 발생하기 쉬운 것을 알고있다. qz과 같은 말도 안되는 이름을 붙이면 그 문제는 더욱 심각해집니다. 매개 변수에 대한 강력한 입력을 이용하면 컴파일시 버그를 제거하여 프로그램을보다 안전하게 유지할 수 있습니다.

+0

주요하게 편집 된 질문. – bigcodeszzer

+0

@bigcodeszzer 답변이 업데이트되었습니다. – erickson

+0

int []가 java의 인스턴스가 아닙니다. 함수 호출이 명령어를 추가하면 가능한 많은 래퍼 코드를 잘라내는 것이 더 효율적으로 보일 것입니다. – bigcodeszzer

1

아키텍처 보안과 언어 보안을 구분하십시오. 대부분의 컴퓨터 과학 교수는 실제로 그것을 인식하지 못합니다.

개체를 "안전하게"전달하려면 키보드에서 암호화 키를 요구할 수 있습니다. 열쇠를 모으고; 객체를 암호화한다. 그것을 전달하십시오. 수신 함수는 다시 암호화하고 암호화를 되돌릴 수 있습니다! 그것은 모두 당신이 성취하고자하는 것에 달려 있습니다.

개체의 수명이 가장 중요합니다. 일단 전달되면, 매개 변수 값은 스택에 위치합니다. 우리가 JVM에 속한 메모리 위치를 볼 수있는 관찰자를 가정한다면, 우리는 엉성해진다. 따라서 일단 값이 검색되면 in situ 쓰레기를 덮어 씁니다. 우리는 이것을 객체 재사용이라고 부릅니다. 객체를 시스템으로 다시 가져올 때 우리는 일반적으로 염두에 둡니다. 우리는 우리의 주소 공간을 공유하고 계속해서 여기에서 엿보고 거기서 파고들 것을 암묵적으로 가정하지 않습니다.

+0

질문이 많이 편집되었습니다. – bigcodeszzer

1

처음에는 4 개의 int가 있고 결국에는 Rectangle이 필요합니다. 입력 내용의 유효성을 확인하고 변환을 수행하는 것이 누구에게 책임이 있는지 알아보십시오.

이 특정 예제는 매우 간단하지만, 당신은 추가하여이 더 재미있게 만들 수 :

public void addRect(String rect){ 
    // e.g. rect = "4 2 3 7" 
} 

public void addRect(int[] rect){ 
    // e.g. rect = [4 2 3 7] 
}  

// etc... 

이 경우는 호출자가 사각형 가 어떻게 구성되는지 신경 쓰지해야한다고 주장하고 있다고 할 수있다 MyCanvas 클래스의 비즈니스입니다

+0

나는 그것을 좋아한다. ... – bigcodeszzer

관련 문제