1. Class类
- 在面向对象的世界里,万事万物皆对象。
java语言里,静态的成员、普通数据类型类不是对象。 - 类是谁的对象?
类是对象,类是java.lang.Class类的实例对象。 - 如何实例化对象?
- 使用new创建一个对象
package Test903;
public class Test {
public static void main(String[] args) {
//Foo的实例对象如何表示
Foo foo=new Foo();
}
}
class Foo{
}
- Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢?任何一个类都是Class类的实例化对象,三种实例化方式:
- 第一种:调用Object类中的
getClass()
方法。 - 第二种:使用
类.class
取得,之前是产生了类的实例化对象之后取得的class对象,但是此时并没有取得实例化对象。也就是说,任何一个类都有一个隐含的静态成员变量class。 - 第三种:调用class类的一个方法
Class.forName()
。
package Test903;
public class Test {
public static void main(String[] args) {
//Foo的实例对象如何表示
Foo foo=new Foo();
//Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢
//任何一个类都是Class类的实例化对象
//第一种表达方式:任何一个类都有一个隐含的静态成员变量class
Class c1=Foo.class;
//第二种表达方式:已知该类的对象,通过getClass方法
Class c2=foo.getClass();
/*c1,c2表示了Foo类的类类型(class type),万事万物皆对象,类也是对象
* 是class类的实例对象*/
System.out.println("第一种方式"+c1);
System.out.println(c1==c2);//true
//第三种方式:
Class c3=null;
try {
c3=Class.forName("Test903.Foo");
}catch (Exception e){
e.printStackTrace();
}
System.out.println(c2==c3);//true
}
}
class Foo{
}
- 通过类的类类型创建该类的对象实例,即通过c1,c2,c3创建类Foo的实例化对象,实例化对象方法:
public T newInstance() throws InstantiationException,IlleagalAccessException
- 前提要求:需要无参构造方法
- 程序代码:
package Test903;
public class Test {
public static void main(String[] args) {
//Foo的实例对象如何表示
Foo foo = new Foo();
//Foo这个类,也是一个实例对象,即Class类的实例对象,如何表示呢
//任何一个类都是Class类的实例化对象
//第一种表达方式:任何一个类都有一个隐含的静态成员变量class
Class c1 = Foo.class;
//第二种表达方式:已知该类的对象,通过getClass方法
Class c2 = foo.getClass();
/*c1,c2表示了Foo类的类类型(class type),万事万物皆对象,类也是对象
* 是class类的实例对象*/
System.out.println("第一种方式" + c1);
System.out.println(c1 == c2);//true
//第三种方式:
Class c3 = null;
try {
c3 = Class.forName("Test903.Foo");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(c2 == c3);//true
Foo foo1 = null;
try {
foo1 = (Foo) c1.newInstance(); //需要强制类型转换,需要无参构造方法
} catch (Exception e) {
e.printStackTrace();
}
boolean flag = foo1 instanceof Foo;
System.out.println("是不是Foo的对象: " + flag);
foo1.print();
}
}
class Foo {
public void print() {
System.out.println("这个Foo类的print方法");
}
}
2. 动态加载类
Class.forName("类的全称")
,不仅表示了类的类类型,还代表了动态加载类。- 编译时刻加载类是静态加载类,运行时刻加载类是动态加载的。
- new创建对象是静态加载类,在编译时刻就需要加载所有的可能用到的类
Class.forName()
动态加载类,在运行时刻加载
3. java获取方法信息
- 获取类名称:
getName()
- 获取类的信息:
getClass()
- Method类,方法对象,一个成员方法就是一个Method对象。
getMethods()
方法获取所有public的函数,包括父类继承而来的getDeclaredMethods()
获取所有该类自己声明的方法
package Test903;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
Class c1=int.class;
Class c2=String.class;
Class c3=double.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c1.getClass());
System.out.println(c1.getName());
/*
Method类,方法对象,一个成员方法就是一个Method对象
getMethods()方法获取所有public的函数,包括父类继承而来的
getDeclaredMethods()获取所有该类自己声明的方法
*/
Method[] ms=c2.getMethods();
//c1.getDeclaredMethods();
for (int i = 0; i <ms.length ; i++) {
//得到方法返回值类型的类类型
Class returnType=ms[i].getReturnType();
System.out.println(returnType.getName()+" ");
//得到方法的名称
System.out.print(ms[i].getName()+"(");
//获取参数类型,得到参数列表的类型的类类型
Class[] paramTypes=ms[i].getParameterTypes();
for (int j = 0; j <paramTypes.length ; j++) {
System.out.print(paramTypes[j].getName()+",");
}
System.out.println(")");
}
}
}
4. 获取成员变量、构造函数信息
- 成员变量也是对象。
java.lang.reflect.Field
Field类封装了关于成员变量的操作。
- getFileds()方法获取得是所有得public的成员变量的信息
- getDeclaredFields获取的是该类自己声明的成员变量的信息
package Test903;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
Class c1=int.class;
Class c2=String.class;
Class c3=double.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c1.getClass());
System.out.println(c1.getName());
/*
成员变量也是对象,java.lang.reflect.Field
Field类封装了关于成员变量的操作
getFileds()方法获取得是所有得public的成员变量的信息
getDeclaredFields获取的是该类自己声明的成员变量的信息
*/
Field[] fs=c2.getDeclaredFields();//c1.getFields();
for (Field field:
fs) {
//得到成员变量的类型的类类型
Class fieldType=field.getType();
String typeName=fieldType.getName();
//得到成员变量的名称
String fieldName=field.getName();
System.out.println(typeName+" "+fieldName);
}
}
}
- 构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
getConstructors()
方法获取得是所有的public的构造函数getDeclaredConstructors()
获取的是该类自己声明的构造函数
package Test903;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
Class c1=int.class;
Class c2=String.class;
Class c3=double.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c1.getClass());
System.out.println(c1.getName());
/*
构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
getConstructors()方法获取得是所有的public的构造函数
getDeclaredConstructors()获取的是该类自己声明的构造函数
*/
Constructor[] cs=c2.getDeclaredConstructors();
for (int i = 0; i < cs.length; i++) {
System.out.print(cs[i].getName()+"(");
Class[] paramTypes=cs[i].getParameterTypes();
for (int j = 0; j <paramTypes.length ; j++) {
System.out.print(paramTypes[j].getName()+",");
}
System.out.println(")");
}
}
}
5. 反射的基本操作
-
如何获取某个方法?
方法的名称和方法的参数列表才能唯一的确定某个方法
-
利用Method类方法,方法反射的操作
method.invoke(对象,参数列表)
方法没有返回值时返回null,有返回值就返回具体的返回值,但返回的是Object对象,需要做类型转换。