java 反射 注入class_Java反射机制 - Class类的使用

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(在使用时可以自动拆箱)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值