Java学习之反射机制学习笔记--2

2、Class的作用

Class是反射的源头,不仅可以取得对象所在类的信息,也可以通过Class类的方法进行对象的实例化操作,正常情况下,通过new实例化,如果已经实例化好了实例化对象,则可以通过Class类提供的newInstance()完成

package com.reflection.demo2 ;

class Person{
	private String name ;	// name属性
	private int age ;		// age属性
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
	public String toString(){	// 覆写toString()方法
		return "姓名:" + this.name + ",年龄:" + this.age  ;
	}
};
public class InstanceDemo01{
	public static void main(String args[]){
		Class c = null ;		// 声明Class对象
		try{
			c = Class.forName("com.reflection.demo2.Person") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Person per = null ;	// 声明Person对象
		try{
			per = (Person)c.newInstance() ;	// 实例化对象
		}catch(Exception e){
			e.printStackTrace() ;
		}
		per.setName("李兴华") ;		// 设置姓名
		per.setAge(30) ;				// 设置年龄
		System.out.println(per) ;	// 内容输出,调用toString()
	}
};

通过以上代码可以发现,即使不使用关键字new,对象也可以进行实例化操作,反射的作用。但是在以上操作中必须注意,在操作中,类中必须存在无参的构造方法,否则,无法实例化,

package com.reflection.demo2 ;
class Person2{
	private String name ;	// name属性
	private int age ;		// age属性
	public Person2(String name,int age){//有参的构造方法
		this.setName(name) ;
		this.setAge(age);
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
	public String toString(){	// 覆写toString()方法
		return "姓名:" + this.name + ",年龄:" + this.age  ;
	}
};
public class InstanceDemo02{
	public static void main(String args[]){
		Class c = null ;		// 声明Class对象
		try{
			c = Class.forName("com.reflection.demo2.Person") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Person2 per2 = null ;	// 声明Person对象
		try{
			per2 = (Person2)c.newInstance() ;	// 实例化对象
		}catch(Exception e){
			e.printStackTrace() ;
		}
		per2.setName("李兴华") ;		// 设置姓名
		per2.setAge(30) ;				// 设置年龄
		System.out.println(per2) ;	// 内容输出,调用toString()
	}
};


会出现以下错误:

java.lang.ClassCastException: com.reflection.demo2.Person cannot be cast to com.reflection.demo2.Person2
at com.reflection.demo2.InstanceDemo02.main(InstanceDemo02.java:35)
Exception in thread "main" java.lang.NullPointerException
at com.reflection.demo2.InstanceDemo02.main(InstanceDemo02.java:39)

所以,使用以上方法,需要类中无参构造方法的支持,符合于对象的实例化要求,对象只要被实例化,就需要这种操作方式完成。

如果想解决这类问题,则必须明确地指定要调用的构造方法,并传递参数,但是一般从开发的角度来讲,一般使用反射的时候,类中都最好存在一个无参的构造,这样的操作比较合理。

如果要调用有参,则必须按照如下的步骤进行:

1,通过Class类的getConstructors()方法取得本类中的全部构造方法;

2,向构造方法中传递一个对象数组进去,里边包含了构造方法中所需的各个参数;

3,再通过Constructor实例化对象

Constructor中存在一个方法,可以传递初始化参数,已进行实例化操作

package com.reflection.demo2 ;
import java.lang.reflect.Constructor ;	// 导入反射机制包
class Person3{
	private String name ;	// name属性
	private int age ;		// age属性
	public Person3(String name,int age){
		this.setName(name) ;
		this.setAge(age);
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
	public String toString(){	// 覆写toString()方法
		return "姓名:" + this.name + ",年龄:" + this.age  ;
	}
};
public class InstanceDemo03{
	public static void main(String args[]){
		Class c = null ;		// 声明Class对象
		try{
			c = Class.forName("com.reflection.demo2.Person") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Person3 per3 = null ;	// 声明Person对象
		Constructor cons[] = null ;
		cons = c.getConstructors() ;
		try{
			per3 = (Person3)cons[0].newInstance("李兴华",30) ;	// 实例化对象
		}catch(Exception e){
			e.printStackTrace() ;
		}
		System.out.println(per3) ;	// 内容输出,调用toString()
	}
};

从实际角度看,如果要使用反射进行对象的实例化操作,最后在类中存在无参构造


你可能感兴趣的:(java)