Class类的使用
类是对象,类是java.lang.Class类的实例对象。
如何表示Class类的实例呢?
任何一个类都是Class类的实例对象,这个实例对象有三种表示方式:
创建一个类
class Foo{
}
第一种表达方式-->实际在告诉我们任何一个类都有一个隐含的静态成员class
Class c1 = Foo.class;
第二种表达方式。已经知道该类的对象通过getClass方法。
Foo foo1 = new Foo();
Class c2 = foo1.getClass();
官网c1,c2表示了Foo类的类类型(class type)万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们成为该类的类类型
不管c1 or c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象。
第三种表达方式 //会有异常
Class c3 = null;
c3 = Class.forName("包名.类名");
我们完全可以通过类的类类型创建该类的对象实例-->
前提要求是需要有无参数的构造方法。
通过c1 or c2 or c3创建Foo的实例对象
Foo foo = (Foo)c1.newInstance()//会有异常
动态加载类:
Class.forName("类的全称");
不仅表示了类的类型,还表示了动态加载类
编译时刻加载类是静态加载类,运行时刻加载类是动态加载类
代码:
class Office
{
public static void main(String[] args){
if("word".equals(args[0])){
word w = new word();
w.start();
}
}
}
当编译以上代码会出现错误,因为没有word和Excle这两个类,当创建成功word类后,还是有错误,因为Excle任然是不存在的。
我们的目的是,用到什么类加载什么类,我们希望运行时加载。
new创建对象,是静态加载类,在比哪一时刻就需要加载所有可能使用到的类。
通过动态加载类可以解决该问题。
class Office
{
public static void main(String[] args) throws Exception{
//动态加载类,在运行时刻加载
Class c = Class.forName(args[0]);
//通过类类型,创建该类对象
//此中类名是word和Excle的接口或父类。多态
类名 变量名 = (类名)c.newInstance();
}
}
Class类的一些基本方法:
public String getName()以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
public String getSimpleName()返回源代码中给出的底层类的简称。
public Method[] getMethods()throws SecurityException返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口的公共 member 方法
getRunType();//得到方法的返回值类型的类类型
public Method[] getDeclaredMethods() throws SecurityException返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
获取成员变量的一些信息:
成员变量也是对象
java.labg.reflect.Field
Field类封装了关于成员变量的操作
getFields()方法获取的是所有的public的成员变量的信息
getDeclaredFields获取的是该类自己声明的成员变量的信息
Field[] fs = c.getFields();
getType()方法获取的是成员变量的类型的类类型
获取构造方法的信息:
构造函数也是对象;
java.lang.Constructor中封装了构造函数的信息
c.getConstructor()//获得所有的public的构造方法
getDeclaredConstructor()//得到所有的构造函数
获得构造函数的参数列表的类类型
constructors.getParameterTypes();
方法的反射操作:
1、如何获取某个方法:方法的名称和参数列表才能唯一决定某个方法
getMethod()获取的是public的方法
getDelcaredMethod()获取的是自己声明的方法
2、方法的反射操作:是指用m对象来进行方法调用
方法如果没有返回值返回null,有返回值返回具体的返回值
m.invoke(操作方法的对象,new Object[]{参数列表});
m.invoke(操作方法的对象,参数列表);
21.反射之修改成员属性
格式:1.创建对象
2.获取类名.class对象
3.用
,public class Test3 {
public static void main(String[] args) throws Exception {
A c = new A("kb kb kb ");
Class<?> c= A.class;
或:
Class c = Class.forName("A");
Field f = A.class.getDeclaredField("a");
System.out.println(c.a);
f.set(c, "fuck");
System.out.println(c.a);
}
}
class A{
String a;
A(String a){
this.a=a;
}
22,反射之获取构造方法
1.当只需要获得无参构造成的对象时
String name = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//如何产生该类的对象呢?
Object obj = clazz.newInstance();
2.当想获取有参构造的对象.
String name = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//获取到了指定的构造函数对象。
Constructor constructor = clazz.getConstructor(String.class,int.class);(这里传构造方法参数类型的字节码对象)
//通过该构造器对象的newInstance方法进行对象的初始化。
Object obj = constructor.newInstance("小明",38);(直接传构造方法参数)
Constructor[] constructor = clazz.getConstructors();
这是获取包含所有按由上至下的构造方法的,一个数组
23,反射之获取成员方法
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("paramMethod", String.class,int.class);
//参数(方法名,方法参数1的字节码对象1,方法参数2的字节码对象)
Object obj = clazz.newInstance();
method.invoke(obj, "小强",89);(本类对象,方法参数1,方法参数二)