-Class类
Java中手动创建的每一个类,在编译后JVM都会为其创建一个Class类对象,在这个Class类对象中保存了所建类的信息。
可通过Class类提供的方法为一个类实例化对象,区别与new关键字创建对象,前者是在类已经编译好的情况下,通过指定类名来创建实例化对象,后者是在编译之后之间创建实例化对象。
也可通过Class类在运行时获得某个类对象的信息。
下面是获取Class类对象的三种方法。
package org.test;
/**
* @ClassName: TestDemo
* @Description: 获取Class类对象的三种方法
* @author 王逍遥
* @date 2018-6-8 下午1:13:56
*/
class Person{}
public class TestDemo {
public static void main(String args[]) throws ClassNotFoundException{
Person per = new Person();
/*
* getClass()取得Person的Class类对象,Object类提供此方法
* 看源码可知getClass()返回的是Class<?>,per.getClass()取得的就是Person类的Class类对象
* */
System.out.println(per.getClass().getName()); //输出Class类对象中Person类的信息
Class<?> cls = Person.class; //Person.class,取得Person类的Class类对象
System.out.println(cls.getName()); //输出Class类对象中Person类的信息
Object obj = Class.forName("org.test.Person");
System.out.println(obj.getClass().getName());
Class<?> cls2 = Class.forName("org.test.Person"); //forName通过全限定名获取Class类对象
System.out.println(cls2.getName()); //输出Class类对象中Person类的信息
}
}
通过反射实例化对象:
package org.test;
/**
* @ClassName: TestDemo02
* @Description: 反射实例化对象
* @author 王逍遥
* @date 2018-6-8 下午1:13:56
*/
class Person {
public Person() {
System.out.println("**************"); //由这个输出可知,反射实例化对象也要调用构造方法
}
}
public class TestDemo {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class<?> cls = Class.forName("org.test.Person"); //通过类全限定名获取Person的Class类对象
Person per = (Person) cls.newInstance(); // newInstance()实例化对象
System.out.println(per);
}
}
newInstance()在运行时实例化对象,关于运行时这一点,可以参考工厂模式与反射的结合,即只需要更改主方法中的类全限定名参数,就可以增加实例化对象。
-总结
Java可以通过反射机制来实例化一个对象,也可用反射调用构造方法,指定构造方法参数,另外还有反射调用方法、属性等。反射加强了Java的配置性和扩展性(比如反射与工厂模式的集合),Spring框架提供的许多功能都是Java反射来实现,SpringIoC就是。
另外疑问ssm框架中许多可写在Java代码中的内容都用*.xml来代替,这是否也与反射相关呢?
补上反射调用构造方法,方法的代码:
package org.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @ClassName: Temp
* @Description: 反射调用构造方法
* @author 王逍遥
* @date 2018-6-11 上午8:34:07
*/
class Person(){
private String name;
private int age;
public Person(){}
public Person(String name, int age) {
this.name = name ;
this.age = age ;
System.out.println("------------------");
}
public String toString() {
return "姓名:" + this.name + ",年龄:" + this.age;
}
}
public class Temp {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> cls = Class.forName("org.test.Person");
//创建per对象,无参
Person per = (Person) cls.newInstance();
System.out.println(per);
//构造参数创建对象,添加参数
Constructor<?> cons=null;
cons=cls.getConstructor(String.class,int.class);//获取指定参数的构造方法
Person per2 = (Person) cons.newInstance("hehe",3);//创建新对象时调用构造方法
System.out.println(per2);
}
}
package org.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ClassName: ReflectDemo03
* @Description: 反射调用普通方法
* @author 王逍遥
* @date 2018-6-11 上午8:47:15
*/
class Person{
//无参无返回值
public void test(){
System.out.println("heiheiheihei");
}
//有参无返回值
public void test02(String temp){
System.out.println(temp);
}
//有参有返回值
public String test03(String temp){
return temp;
}
}
public class ReflectDemo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> cls=Class.forName("org.test.Person");
//提供一个统一的对象来调用方法
Object obj = cls.newInstance();
//无参无返回值
Method met = cls.getMethod("test");
met.invoke(obj);
//有参无返回值
Method met2 = cls.getMethod("test02", String.class);
met2.invoke(obj, "hehehehehe");
//有参有返回值
Method met3 = cls.getMethod("test03", String.class);
//用re来接收返回的内容
Object re = met3.invoke(obj, "hahahahaha");
System.out.println(re);
}
}