[221117]研修17日目
Staticインスタンスを必要とせずに 「Cの一般関数と同じ」
したがって,クラスで宣言する場合,メンバ関数を区別するためにstaticというキーワードを用いる.
static initializer
試験137時間第1回試験137.classのみ使用します.new Temp()に遭遇した場合、Temp.classが必要でTempclassはメモリにロードする必要があります.次に、インスタンスがロードされたクラスとして作成されます.
このとき(クラスロード時)静的に関連するメンバー変数と関数の作成時間はclassがロードされたときです.このときnon-staticメンバーはまだ現れていません. staticでnon-staticメンバーは使用できません!
Singleton Pattern
getMethod objは、各関数を呼び出す を指す. argsはパラメータ値 に渡す
戻りは、関数の戻り値 に相当する.
Class> cls
1. Class.forName("banana.Temp");
2.「クラス名」.class
3.Objectで宣言したgetClass()関数を呼び出す
強化されたfor文
class Temp {
static int add( int i, int j ) { return 100; }
}
//
public class Test136 {
public static void main( String[] args ) {
int r = Temp.add( 10, 20 );
System.out.println( r );
}
}
static付きメンバー関数は?클래스명.함수명
を呼び出すことができます.(参照変数は不要)int add( int i , int j ) {
return 100;
}
int main() {
int r;
r = add( 10, 20 );
printf("%d\n", r );
return 0;
}
Cはクラス外で関数を宣言できますがjavaはできません.したがって,クラスで宣言する場合,メンバ関数を区別するためにstaticというキーワードを用いる.
static initializer
class Temp {
static {
System.out.println("static");
}
//
Temp() {
System.out.println("생성");
}
}
//
public class Test137 {
public static void main( String[] args ) {
new Temp();
new Temp();
new Temp();
}
}
static initializer
:インスタンスを作成する前に1回のみ呼び出されます.つまり、クラスはロード時に呼び出されます.試験137時間第1回試験137.classのみ使用します.new Temp()に遭遇した場合、Temp.classが必要でTempclassはメモリにロードする必要があります.次に、インスタンスがロードされたクラスとして作成されます.
このとき(クラスロード時)
static initializer
が呼び出されます.インスタンスの作成時にメンバーを指す関数ポインタにはメモリが割り当てられるため、クラスのロード時にメンバーを呼び出すことはできません.class Temp {
static { // 얼마든지 OK
Temp t = new Temp();
t.print();
}
static void print2() {
// 에러 : print();
}
void print() {
print2();
}
}
/*
인터페이스는 오버라이딩을 전제로 하는 함수를 가진다.
오버라이딩은 함수 포인터로 운용되어야하므로 인스턴스에 함수포인터가 있어야 한다.
따라서 인터페이스 안에서는 non-static 한 메소드를 사용해야 한다.
*/
interface ITemp {
// public static void print();
}
//
public class Test138 {
public static void main( String[] args ) {
//...
}
}
non-static method print() cannot be referenced from a static context
Singleton Pattern
class Temp {
// uniq 변수는 jvm 안에 유일하게 된다.
private static Temp uniq = null;
// static initializer 안에서 uniq 로 인스턴스를 가리키게 하라.
static {
uniq = new Temp();
}
// public static synchronized 하게 uniq 를 제공하는 getInstance 함수를 선언한다.
public static synchronized Temp getInstance() {
return uniq;
}
// Temp 밖에서는 생성자를 호출할 수 없다. 즉 인스턴스를 못 만든다.
private Temp() { }
} // 이렇게 설계하는 설계 패턴을 Singletone Pattern 이라고 한다.
//
public class Test139 {
public static void main( String[] args ) {
// 에러 new Temp();
Temp a = Temp.getInstance();
Temp b = Temp.getInstance();
System.out.println( a == b ); // 인스턴스가 재활용되고 있고 공유되고 있음.
}
}
class Temp {
private static Temp uniq = null;
// 처음 호출시에 인스턴스가 생성되고 , 그 이후에는 인스턴스는 재활용된다.
public static synchronized Temp getInstance() {
if( uniq == null ) {
uniq = new Temp();
}
return uniq;
}
private Temp() { }
}
クラスの読み込みpackage banana;
class Temp {
static {
System.out.println("static");
}
public void print() {
System.out.println("print");
}
}
//
public class Test141 {
public static void main( String[] args ) throws Exception {
Class<?> cls = Class.forName("banana.Temp");
Object obj = cls.newInstance();
System.out.println( obj.getClass().getName() );
}
}
Class.forName
:文字列に指定された名前のクラスを強制的にロードします.Object obj = cls.newInstance()
:clsに対応するクラスインスタンスを作成します.newなしでインスタンスを作成getMethod
package banana;
import java.lang.reflect.Method;
//
class Temp {
public void print() {
System.out.println("print");
}
}
public class Test143 {
public static void main( String[] args ) throws Exception {
Temp t = new Temp();
t.print();
//
Class<?> cls = Class.forName("banana.Temp");
Object obj = cls.newInstance();
System.out.println( obj );
//
Method mtd = cls.getMethod("print");
mtd.invoke( obj );
}
}
関数名を文字列として呼び出すことができますgetMethod
:clsはprintという名前の関数を呼び出すポインタを提供していると思います.invoke
:関数を呼び出す場合は、インスタンスにポインタ(obj)を付ける必要があります.import java.lang.reflect.Method;
//
class Temp {
public void print( int i ) {
System.out.println("Hello " + i );
}
public void print() {
System.out.println("Apple" );
}
public void print( int i, double j ) {
System.out.println("Banana" + j );
}
}
//
public class Test148 {
public static void main( String[] args ) throws Exception {
Class<?> cls = Class.forName("banana.Temp");
Object obj = cls.newInstance();
// cls 에 선언된 이름이 print 이고 매개변수가 int 로 선언된 함수 포인터를 넘긴다.
Method mtd = cls.getMethod("print", int.class );
mtd.invoke( obj, 100 );
// getMethod 는 가변길이 파라미터를 쓰는 형태를 지원
Method mtd2 = cls.getMethod("print", int.class, double.class );
Object rv = mtd2.invoke( obj, 100, 3.14 );
System.out.println( rv );
}
}
public Object invoke(Object obj, Object... args)
인스턴스
のポインタ戻り
Class> cls
class Temp {
public int print() {
System.out.println("Apple" );
return 100;
}
}
//
public class Test149 {
public static void main( String[] args ) throws Exception {
Class<?> cls = Class.forName("banana.Temp");
Object obj = cls.newInstance();
//
System.out.println( Temp.class == cls );
System.out.println( obj.getClass() == cls );
// invoke 함수의 리턴타입은 Object 니까 언박싱을 이용하여 자료형변수에 대입하려면 캐스팅 필요
Method mtd = cls.getMethod("print");
int r = (Integer)mtd.invoke( obj );
System.out.println( r );
}
}
Class<?> cls = ...
を使用してポインタを取得1. Class.forName("banana.Temp");
2.「クラス名」.class
3.Objectで宣言したgetClass()関数を呼び出す
強化されたfor文
class Temp {
public void print( int i, int j ) {
System.out.println("Apple" );
}
}
//
public class Test150 {
public static void main( String[] args ) throws Exception {
Class<?> cls = Class.forName("banana.Temp");
Object obj = cls.newInstance();
//
Method[] mtds = cls.getMethods();
for( Method mtd : mtds )
{
System.out.println( mtd.getName() );
}
}
}
配列、List、Setに使用できます.Reference
この問題について([221117]研修17日目), 我々は、より多くの情報をここで見つけました https://velog.io/@choiyezz/211117-교욱-17일차テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol