一,Class类
万事万物皆对象,类也是对象,类是 java.lang.Class 类的对象
这个对象有三种获取方法:
Class c1=ClassName.class;//由类名来获取类类型
ClassName a=new fo(); //由类对象来获取类类型
Class c2=a.getClass();
Class c3=Class.forName("packageName.ClassName");//由Class类的forName方法来获取
二,动态加载类
new 创建对象是静态加载类,在编译时刻就加载可能用到的类
通过动态加载类即用到的类才加载
Class c=Class.forName(arg[0]); //动态加载类,在运行时刻加载
Word w=(Word)c.newInstance(); //通过类类型来创建类对象
三,Class类的基本API操作(获取类方法的类类型)
1.通过对象来获取类类型,然后通过该类类型来获取全部方法及方法的返回值类型,参数,参数类型
public class ClassUtil {
public static void printClassMessage(Object obj){
Class c=obj.getClass(); //通过对象来获取类类型
System.out.println("类的名称是:"+c.getName());
Method[] ms=c.getMethods(); //获取该类类型的所有方法的类类型的数组
for (int i = 0; i < ms.length; i++) {
Class returnType=ms[i].getReturnType(); //得到方法返回值类型的类类型,比如String得到String.Class
System.out.print(returnType.getName()+" ");
System.out.print(ms[i].getName()+"("); //得到方法的名称
Class [] paramTypes=ms[i].getParameterTypes();//得到的是参数列表的类型的类类型 比如int得到int.Class
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+" ");
}
System.out.println(")");
}
}
}
test类
public class ClassTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="hello";
ClassUtil.printClassMessage(s);
}
}
类的名称是:java.lang.String
boolean equals(java.lang.Object )java.lang.String toString()int hashCode()int compareTo(java.lang.String )int compareTo(java.lang.Object )
int indexOf(java.lang.String int )
int indexOf(java.lang.String )
int indexOf(int int )
int indexOf(int )
。。。。。。省略,至此获取该String.Class的全部方法
2.
成员变量也是对象,是java.lang.reflect.Field的对象
Field类封装了关于成员变量的操作
getFields()方法获取的是所有的public的成员变量的信息
getDeclaredFields获取的是该类自己声明的成员变量的信息
public static void printClassField(){
Field[] fs=c.getDeclaredFields();
for(Field field:fs){
Class fieldType=field.getType(); //得到成员变量的类型的类类型
String typeName=fieldType.getName();
String fieldName=field.getName(); //得到成员变量的名称
System.out.println(typeName+" "+fieldName);
}
}
3.
构造函数也是对象,是java.lang.Construtor中封装了构造函数的信息
getDeclaredConstrutors得到所有的构造函数
public static void printConMessage(Object obj){
Class c=obj.getClass();
Constructor[] cs=c.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.print(constructor.getName()+"(");
Class [] paramTypes=constructor.getParameterTypes(); //得到构造函数的参数列表的类类型
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}
三,方法的反射
1,通过方法的名称和方法的参数列表才能唯一决定某个方法
2,方法反射的操作
method.invoke(对象,参数列表)
package reflect;
import java.lang.reflect.Method;
public class MethodTest {
public static void main(String[] args) {
A a=new A();
Class c=a.getClass();
Method m;
try{
m=c.getMethod("print",int.class,int.class);
Object o= m.invoke(a, new Object[]{10,20}); //方法没有返回值就返回null,有返回值返回具体的返回值
System.out.println("=============");
Method m1=c.getMethod("print", new Class[]{"hello".getClass(),"word".getClass()});
Object o1=m1.invoke(a, "hello","word"); //传入对象,方法的实参
}catch(Exception e){
e.printStackTrace();
}
}
}
class A{
public void print(int a,int b){
System.out.println(a+b);
}
public void print(String a,String b){
System.out.println(a.toUpperCase()+","+b.toLowerCase());
}
}
结果:
30
=============
HELLO,word
四,反射的操作都是编译之后的操作
java集合的泛型,实防止错误输入,只在编译阶段有效
public class MethodDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList list=new ArrayList<>();
ArrayList<String> list1=new ArrayList<>();
Class c1=list.getClass();
Class c2=list1.getClass();
System.out.println(c1==c2);
}
}
返回
true