programing

"Class.forName()"과 "Class.forName().newInstance()"의 차이점은 무엇입니까?

bestcode 2022. 9. 15. 23:59
반응형

"Class.forName()"과 "Class.forName().newInstance()"의 차이점은 무엇입니까?

Class.forName() ★★★★★★★★★★★★★★★★★」Class.forName().newInstance()

나는 그 차이를 이해할 수 없다(그들에 대해 뭔가 읽은 적이 있다!).도와주실 수 있나요?

두 가지 방법이 어떻게 사용되는지 보여주는 예가 상황을 더 잘 이해하는 데 도움이 될 수 있습니다.따라서 다음 클래스를 고려하십시오.

package test;

public class Demo {

    public Demo() {
        System.out.println("Hi!");
    }

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("test.Demo");
        Demo demo = (Demo) clazz.newInstance();
    }
}

javadoc에서 설명한 바와 같이 calling은 지정된 문자열 이름의 클래스 또는 인터페이스와 관련된 개체를 반환합니다.즉, 반환됩니다.test.Demo.class.clazz 「」의 Class.

그런 다음 호출하면 이 객체가 나타내는 클래스의 새 인스턴스가 생성됩니다. 인수 목록이 비어 있는 식에 의해 클래스가 인스턴스화됩니다.즉, 이것은 실제적으로 1차적으로new Demo()됩니다.Demo.

이 실행 중.Demo수업

Hi!

의 존존 의 큰 new라는 것이다.newInstance실행 시까지 알 수 없는 클래스를 인스턴스화하여 코드를 보다 역동적으로 만들 수 있습니다.

일반적인 예로는 실행 시 작업을 수행하는 데 필요한 정확한 드라이버를 로드하는 JDBC API가 있습니다.EJB 컨테이너, Servlet 컨테이너도 다른 좋은 예입니다. 즉, 동적 런타임 로딩을 사용하여 런타임 전에 아무것도 모르는 구성요소를 로드하고 생성합니다.

사실, 더 나아가고 싶다면 바로 위의 단락에서 설명한 Ted Neward 논문 Understanding Class.forName()을 참조하십시오.

EDIT(코멘트로 게시된 OP의 질문에 답변):JDBC 드라이버의 경우는 조금 특별합니다.JDBC API를 시작하기 위한 드라이버 매니저 장에서 설명한 바와 같이

(...) ADriver됩니다.DriverManager 두 중 즉 '두 가지'입니다

  1. Class.forName드라이버 클래스를 명시적으로 로드합니다.셋업에 에, 이 은, 「드라이버 로드 방법」을 합니다.DriverManager를 참조할 수 있습니다.합니다.acme.db.Driver:

     Class.forName("acme.db.Driver");
    

이 로드되면 인스턴스가 생성되고 해당 인스턴스가 파라미터(필요한 대로)로서 호출되도록 기술되어 있는 경우, 그 인스턴스는DriverManager접속 작성에 사용할 수 있는 드라이버 목록입니다.

  1. (...)

모두 입니다.Driver는 "class"를 호출하여 합니다.DriverManager.registerDriver앞에서 설명한 바와 같이 이 작업은 클래스가 로드될 때 자동으로 수행되어야 합니다.

초기화중에 자신을 등록하기 위해서, 통상, JDBC 드라이버는 다음과 같은 스태틱 초기화 블록을 사용합니다.

package acme.db;

public class Driver {

    static {
        java.sql.DriverManager.registerDriver(new Driver());
    }
    
    ...
}

" "Class.forName("acme.db.Driver")는, 을 하는 원인이 됩니다.acme.db.Driver아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다. ★★★★★★★★★★★★★★★★★.Class.forName("acme.db.Driver")는 실제로 인스턴스를 "작성"하지만 이는 (정상적인) JDBC 드라이버가 구현되는 방법의 결과일 뿐입니다.

참고로 JDBC 4.0(Java 7 이후 기본 패키지로 추가)과 JDBC 4.0 드라이버의 새로운 자동 로딩 기능에서는 이 모든 것이 더 이상 필요하지 않습니다.Java SE 6 의 JDBC 4.0 확장 기능을 참조해 주세요.

class.forName()은 Class.forName()을 사용합니다.이 객체의 메서드는 클래스를 작성하는 프로그래머가 아니라 Java에 의해 정의됩니다.이치노 "newInstance()"를 호출합니다.Class.forName("ExampleClass").newInstance()라고 부르는 것과 new ExampleClass()클래스 정의 메서드를 호출하여 표시되는 필드 등에 액세스 할 수 있습니다.

JDBC 세계에서는 (JDBC API에 따라) 일반적인 방법은Class#forName()JDBC 드라이버를 로드합니다.JDBC 드라이버는 스태틱블록 내부에 등록해야 합니다.

package com.dbvendor.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;

public class MyDriver implements Driver {

    static {
        DriverManager.registerDriver(new MyDriver());
    }

    public MyDriver() {
        //
    }

}

호출Class#forName()모든 스태틱 이니셜라이저를 실행합니다.이쪽에서DriverManager는, 접속 URL 에 의해서, 등록된 드라이버에 관련 붙여진 드라이버를 검색할 수 있습니다.이 기간 동안 대략 다음과 같습니다.

public static Connection getConnection(String url) throws SQLException {
    for (Driver driver : registeredDrivers) {
        if (driver.acceptsURL(url)) {
            return driver.connect(url);
        }
    }
    throw new SQLException("No suitable driver");
}

하지만 버그가 있는 JDBC 드라이버도 있었습니다.org.gjt.mm.mysql.Driver잘 알려진 예로서, 이 예에서는 스태틱블록이 아닌 컨스트럭터 내에 잘못 등록됩니다.

package com.dbvendor.jdbc;

import java.sql.Driver;
import java.sql.DriverManager;

public class BadDriver implements Driver {

    public BadDriver() {
        DriverManager.registerDriver(this);
    }

}

동적으로 동작시키는 유일한 방법은newInstance()나중에!그렇지 않으면 첫눈에 설명할 수 없는 "SQLException: 적절한 드라이버 없음"에 직면하게 됩니다.이것은 JDBC 드라이버의 버그이며, 독자적인 코드가 아닙니다.현재 JDBC 드라이버에는 이 버그가 포함되어 있지 않습니다.그래서 당신은 (그리고 그래야 한다)newInstance()떨어져.

1 : 클래스의 스태틱블록에만 관심이 있는 경우 클래스만 로드하면 스태틱블록이 실행됩니다.필요한 것은 다음과 같습니다.

Class.forName("Somthing");

2 : 클래스를 로드하고 스태틱블록을 실행하고 그 비 스태틱 부분에 액세스하려면 인스턴스가 필요하고 그 다음에 다음이 필요합니다.

Class.forName("Somthing").newInstance();

Class.forName()은 클래스, Class.forName()에 대한 참조를 가져옵니다.newInstance()는 클래스가 no-arg 컨스트럭터를 사용하여 새 인스턴스를 반환하려고 합니다.

"Class.forName()"은 지정된 이름의 클래스 유형을 반환합니다."new Instance()"는 이 클래스의 인스턴스를 반환합니다.

유형에서는 인스턴스 메서드를 직접 호출할 수 없고 클래스에 대한 반사만 사용할 수 있습니다.클래스의 오브젝트를 조작하려면 오브젝트의 인스턴스를 작성해야 합니다(「new MyClass()」를 호출하는 것과 같음).

Class.forName()의 예

Class myClass = Class.forName("test.MyClass");
System.out.println("Number of public methods: " + myClass.getMethods().length);

Class.forName().newInstance()의 예

MyClass myClass = (MyClass) Class.forName("test.MyClass").newInstance();
System.out.println("String representation of MyClass instance: " + myClass.toString());

위의 답변에 추가하기만 하면 메모리에 존재할 필요가 있는 정적 코드(즉, 코드 블록이 인스턴스에 의존하지 않음)가 있는 경우 클래스를 반환하여 Class.forname("someName")을 사용할 수 있습니다.그렇지 않으면 정적 코드가 없는 경우 Class.forname().New Instance("someName")는 객체 수준 코드를 메모에 로드하기 때문에 Class.forname("non"nonstatic memo")를 사용할 수 있습니다.라이

Class.forName() 메서드를 호출하는 횟수에 관계없이 스태틱블록이 실행된 후만 여러 번 호출하지 않습니다.

package forNameMethodDemo;

public class MainClass {

    public static void main(String[] args) throws Exception {
        Class.forName("forNameMethodDemo.DemoClass");
        Class.forName("forNameMethodDemo.DemoClass");
        Class.forName("forNameMethodDemo.DemoClass");
        DemoClass demoClass = (DemoClass)Class.forName("forNameMethodDemo.DemoClass").newInstance();
    }
}


public class DemoClass {
    
    static {
        System.out.println("in Static block");
    }

    {
        System.out.println("in Instance block");
    }
}

출력은 다음과 같습니다.

in Static block
in Instance block

이것.in Static block세 번이 아니라 한 번만 인쇄됩니다.

Class.forName()-->forName()은 Class의 스태틱메서드로 사용자 클래스 객체가 아닌 리플렉션에 사용되는 Class 클래스 객체를 반환하므로 클래스 메서드만 호출할 수 있습니다.getMethods(),getConstructors()기타.

(Runtime given) 클래스의 정적 블록만 실행하고 클래스의 메서드, 컨스트럭터, Modifier 등의 정보만 가져오는 경우 이 개체를 사용할 수 있습니다.Class.forName()

그러나 클래스 메서드(실행 시 지정한 클래스)에 액세스하거나 호출하려면 클래스 클래스의 newInstance 메서드가 대신 수행하도록 개체를 설정해야 합니다.그러면 클래스의 새 인스턴스가 생성되어 반환됩니다.너는 그것을 너의 반에 타이프 캐스팅하기만 하면 된다.

예: 종업원이 당신의 클래스라고 가정합니다.

Class a=Class.forName(args[0]); 

//args[0]=cmd line argument to give class at  runtime. 

Employee ob1=a.newInstance();

a.newInstance()를 사용하여 오브젝트를 작성하는 것과 비슷합니다.new Employee().

이제 클래스에 표시되는 모든 필드 및 메서드에 액세스할 수 있습니다.

언급URL : https://stackoverflow.com/questions/2092659/what-is-the-difference-between-class-forname-and-class-forname-newinstanc

반응형