JAVA泛型と反射
45623 ワード
一、パンチング
異なるデータ構造は同じ操作で汎型です.
1.類使用汎型
1)定義
1)定義
1)定義
1)定義呼び出し
汎型を宣言する時は汎型の上限と下限を指定できます.
1)汎型の上限:TはNumber類またはそのサブクラスしかない.
通常の手順はimport「包.類」です.そしてnewの実用化によって最後に実用化されたオブジェクトがあります.
逆にできますか?
答えは肯定的です.私達は実用化対象からget Class方法を得ることができます.最後に完全な「パケット・クラス」の名称を得ることができます.これは逆の操作です.
注意:反射動作では、すべての操作はObjectで行われます.クラスと配列の参照はすべてObjectで受信できます.
1.lassオブジェクトとクラスのインスタンス化オブジェクト
2.クラスを獲得する
配列や他のデータタイプに対しても、対応するクラス、対応するクラスがあります.
反射を使用してクラスの例示的なオブジェクト(クラスの属性と方法)を取得し、import a.b.c.d.Personの代わりに.
1)上記の方法でクラスの属性にアクセスしたほうがいいです.
2)属性を直接取得することもできます.
プログラムの柔軟性を増やす
クラスの名前(ファイルに入れたり、パラメータを通して伝えたりすることで、コードに死を書かずに、何かを伝えてくれれば、実用化できます.)を使って、異なるオブジェクトを具体化することができます.
異なるデータ構造は同じ操作で汎型です.
1.類使用汎型
1)定義
/**
* , 。
*/
class Person<T> {
// , T
private T age;
// , T
public void setAge(T age) {
this.age = age;
}
// , T
public T getAge() {
return this.age;
}
}
2)呼び出しpublic class Generics {
public static void main(String args[]) {
// , <>
Person<String> p = new Person<String>();
p.setAge("3 years old");
//System.out.println(p.getAge());
printInfo(p);
//<> , int Integer
Person<Integer> p2 = new Person<Integer>();
p2.setAge(3);
//System.out.println(p2.getAge());
printInfo(p2);
Person<?> p3;
// p3
p3 = p;
// ( )
//p3.setAge("4 years");
//
p3.getAge();
}
//Person> , String Integer
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
}
2.方法は汎型を使う1)定義
// ,
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
2)呼び出し//p Person p = new Person();
printInfo2(p);
printInfo2(p2);
printInfo2(p3);
3.サブクラスは汎型(汎型の継承)を使用する1)定義
//
class Student<T> extends Person<T> {
}
//
class Student2 extends Person<String> {
// String, ,
}
2)呼び出し// ,
Student<Integer> s = new Student<Integer>();
//
s.setAge(10);
//
printInfo(s);
// ,
Student2 s2 = new Student2();
// , String
s2.setAge("11 years");
printInfo(s2);
4.インターフェースは汎型を使用する(インターフェース:特殊な父親類)1)定義
interface Person<T> {
public void setAge(T age);
public T getAge();
}
//
class Student<T> implements Person<T> {
T age;
public void setAge(T age){
this.age = age;
}
public T getAge() {
return this.age;
}
}
//
class Student2 implements Person<String> {
// ,
String age;
public void setAge(String age){
this.age = age;
}
public String getAge() {
return this.age;
}
}
public static void main(String args[]) {
// ,
Student<Integer> s = new Student<Integer>();
s.setAge(10);
// , , ,
printInfo(s);
// ,
Student2 s2 = new Student2();
s2.setAge("11 years");
printInfo(s2);
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
5.制限付きパンチング汎型を宣言する時は汎型の上限と下限を指定できます.
1)汎型の上限:TはNumber類またはそのサブクラスしかない.
//T Number Integer, Float
class Student<T extends Number> implements Person<T> {
T age;
public void setAge(T age){
this.age = age;
}
public T getAge() {
return this.age;
}
}
2)泛型の下限:super String>TはString類またはその親類だけである.//super , ( )
class Student<T> implements Person<T> {
T age;
public void setAge(T age){
this.age = age;
}
public T getAge() {
return this.age;
}
}
// ( ? )。 String
public static void printInfo(Person<? super String> p) {
System.out.println(p.getAge());
}
//
Student<String> s = new Student<String>();
s.setAge("10");
printInfo(s);
二、反射通常の手順はimport「包.類」です.そしてnewの実用化によって最後に実用化されたオブジェクトがあります.
逆にできますか?
答えは肯定的です.私達は実用化対象からget Class方法を得ることができます.最後に完全な「パケット・クラス」の名称を得ることができます.これは逆の操作です.
注意:反射動作では、すべての操作はObjectで行われます.クラスと配列の参照はすべてObjectで受信できます.
1.lassオブジェクトとクラスのインスタンス化オブジェクト
Person p=new Person();
// " . "
System.out.println(p.getClass().getName());
JVMは*.クラスファイル(Javaで書いたクラス)をメモリにロードします.つまり、このクラスを記述するために、クラスのパッケージ、クラス名、構造方法、方法、属性などを含みます.このclass objectを使って、オブジェクトを具体化することができます.(メモリの中で一つのクラスに対しては一つのクラスしかないです.このクラスはクラス自体を記述するために使われています.このクラスのObjectを使って実用化対象を作成してもいいです.)三つの方法で一つのクラスのクラスのクラスを獲得することができます.2.クラスを獲得する
//1).Class> c=Class.forName(" . ");
Class<?> c1 = null;
try {
c1 = Class.forName("a.b.c.d.Person");
} catch (ClassNotFoundException e) {
System.out.println(e);
}
System.out.println(c1.getName());
//2).Class> c = new X().getClass();
Person p = new Person();
Class<?> c2 = p.getClass();
System.out.println(c2.getName());
//3).Class> c=X.class;
Class<?> c3 = Person.class;
System.out.println(c3.getName());
3.配列およびその他のタイプのクラス配列や他のデータタイプに対しても、対応するクラス、対応するクラスがあります.
int arr[] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[][] = {{1,2,3,4},{1}};
Class<?> c4 = arr.getClass();
Class<?> c5 = arr2.getClass();
Class<?> c6 = arr3.getClass();
System.out.println(c4.getName());
System.out.println(c5.getName());
System.out.println(c6.getName());
// class
System.out.println((c4 == c5));
// class
System.out.println((c4 != c6));
// , class
Class<?> c7 = int.class;
System.out.println(c7.getName());
4.反射を使ってクラスの例示的なオブジェクトを取得する反射を使用してクラスの例示的なオブジェクト(クラスの属性と方法)を取得し、import a.b.c.d.Personの代わりに.
//Exception , InstantiationException
public static void main(String args[]) throws Exception {
Class<?> c = null;
try {
// Person class object
c = Class.forName("a.b.c.d.Person");
} catch (ClassNotFoundException e) {
System.out.println(e);
}
// (Object , )
Object p = null;
try {
// (Object , ( )),
p = c.newInstance();
} catch (InstantiationException e) {
System.out.println(e);
}
//
// String class
Constructor<?> con = c.getConstructor(String.class);
// ,
Object p2 = con.newInstance("123");
}
5.クラスを取得して呼び出す方法// ( public )
Method set = c.getMethod("setName", String.class);
// , ,
set.invoke(p2, "123");
set.invoke(p, "abc");
// , invoke 1 null
Method get = c.getMethod("getName");//
System.out.println(get.invoke(p));
System.out.println(get.invoke(p2));
set.invoke(p2, "123");// , ,
set.invoke(p, "abc");
// , invoke 1 null
Method get = c.getMethod("getName");//
System.out.println(get.invoke(p));
System.out.println(get.invoke(p2));
6.クラスの属性の読み込みまたは設定1)上記の方法でクラスの属性にアクセスしたほうがいいです.
2)属性を直接取得することもできます.
//(1) , , ,
Field f = c.getField(String name);
//(2) ( private,public ) name
Field name = c.getDeclaredField("name");
// , public , , , ( set )
name.setAccessible(true);
// name
name.set(p, "www");
name.set(p2, "123");
// name
System.out.println(name.get(p));
System.out.println(name.get(p2));
7.反射のメリットプログラムの柔軟性を増やす
クラスの名前(ファイルに入れたり、パラメータを通して伝えたりすることで、コードに死を書かずに、何かを伝えてくれれば、実用化できます.)を使って、異なるオブジェクトを具体化することができます.