Class类最常用的方式就是实例化对象的操作,即可以通过一个给定的字符串(此字符串包
含了完整的“包.类”的路径)来实例化一个类的对象。
一、通过无参构造实例化对象
要想通过Class类本身实例化其他类的对象,则可以使用newInstance()方法,但是必须要
保证被实例化的类中存在一个无参构造方法,代码如下:
例:通过Class类实例化对象
package org.lxh.demo15.getclassdemo;
class Person{
private String name ;
private int age ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age ;
}
}
public class InstanceDemo {
public static void main(String args[]){
Class> c = null ;
try{
c = Class.forName(
"org.lxh.demo15.getclassdemo.Person") ;
//传入要实例化类的完整包 .类名称
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Person per = null ; //声明Person对象
try{
per = (Person) c.newInstance() ; //实例化Person对象
}catch(Exception e){
e.printStackTrace() ;
}
per.setName("李兴华") ;
per.setAge(30) ;
System.out.println(per);
}
}
输出:
姓名:李兴华,年龄:30
从程序的运行结果可以发现,通过Class.forName()方法实例化Class对象之后,直接调用
newInstance()方法就可以根据传入的完整“包.类”名称的方式进行对象的实例化操作,
完全取代了之前使用关键字new的操作方式。
但是在使用以上操作时读者一定要记住一点,被实例化对象的类中“必须存在无参构造方法”,
如果不存在,则肯定是无法实例化的。以下代码为一个错误的操作。
例:错误的代码
package org.lxh.demo15.getclassdemo;
class Person{
private String name ;
private int age ;
public Person(String name , int age){
this.setName(name) ;
this.setAge(age) ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age ;
}
}
public class InstanceDemo {
public static void main(String args[]){
Class> c = null ;
try{
c = Class.forName(
"org.lxh.demo15.getclassdemo.Person") ;
//传入要实例化类的完整包 .类名称
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Person per = null ; //声明Person对象
try{
per = (Person) c.newInstance() ; //实例化Person对象
}catch(Exception e){
e.printStackTrace() ;
}
per.setName("李兴华") ;
per.setAge(30) ;
System.out.println(per);
}
}
出错:
java.lang.InstantiationException: org.lxh.demo15.getclassdemo.Person
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at org.lxh.demo15.getclassdemo.InstanceDemo.main(InstanceDemo.java:40)
Exception in thread "main" java.lang.NullPointerException
at org.lxh.demo15.getclassdemo.InstanceDemo.main(InstanceDemo.java:44)
从以上代码中可以发现,因为类中并没有存在无参构造方法,所以是根本无法直接使用
newInstance()方法实例化的。在此,在使用Class类实例化对象时一定要在类中编写无
参构造方法。
提示:各种高级应用中都提倡类中存在无参构造方法。
在实际的Java程序开发中,反射是最为重要的操作原理,在现在的开发设计中大量地应用
了反射处理机制,如Struts、Sping框架等;在大部分的操作中基本上都是操作无参构造
方法。
二、调用有参构造实例化对象
当然,对于以上程序并非没有解决的方法,可以通过其他的方式进行实例化操作,只是在
操作时需要明确地调用类中的构造方法,并将参数传递进去之后才可以进行实例化操作。
操作步骤如下:
1、通过Class类中的getConstructors()取得本类中的全部构造方法。
2、向构造方法中传递一个对象数组进去 ,里面包含了构造方法中所需的各个参数。
3、之后通过Constructor类,表示的是构造方法。此类的常用方法:
Constructor常用方法
public int getModifiers() 得到构造方法的修饰符
public String getName() 得到构造方法的名称
public Class>[] getParameterTypes() 得到构造方法中参数的类型
public String toString() 返回此构造方法的信息
public T newInstance(Object... initargs) throws Instantiation Exception,
IllegalAccessException,IllegalArgumentException,InvocationTargetException
向构造方法中传递参数,实例化对象
下面先使用newInstance()方法解决实例化对象的问题,其他方法在之后会为读者介绍。
例:调用类中的有参构造
package org.lxh.demo15.getclassdemo;
import java.lang.reflect.Constructor;
class Person{
private String name ;
private int age ;
public Person(String name , int age){
this.setName(name) ;
this.setAge(age) ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age ;
}
}
public class InstanceDemo {
public static void main(String args[]){
Class> c = null ;
try{
c = Class.forName(
"org.lxh.demo15.getclassdemo.Person") ;
//声明Class对象
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Person per = null ; //声明Person对象
Constructor> cons[] = null ; //声明一个表示构造方法的数组
cons = c.getConstructors() ; //通过反射取得全部构造
try{
//向构造方法中传递参数,此方法使用可变参数接收,并实例化对象
per = (Person) cons[0].newInstance("李明",90) ;
}catch(Exception e){ //因为只有一个构造,所以数组下标为0
e.printStackTrace() ;
}
System.out.println(per);
}
}
输出:
姓名:李明,年龄:90
以上程序通过Class类取得了一个类中的全部构造方法,并以对象数组的形式返回,因为显
式地调用了类中的构造方法,且在Person类中只有一个构造方法,所以直接取出对象数组
中的第一个元素即可(下标为0就表示调用第一个构造方法)。在声明对象数组时,必须
考虑到构造方法中参数的类型顺序,所以第一个参数的类型为String,第二个参数的类型为
Integer(在使用时可以自动拆箱)