初始 java 反射机制 (一)

java 反射详解 一

前言

反射是java中十分重要的一部分,初学者往往因为自认为用处不发而放弃对反射机制的学习,然而到后期javaweb以及Android的学期会发现java使用的地方非常多。因此这篇文章献给初学者,希望能够有所帮助。
代码参考了网上众多大牛以及thinking IN java。 侵删。

【案例1】通过一个对象获得完整的包名和类名

package Reflect;

/**
* 通过一个对象获得完整的包名和类名
 * */
class Demo{
//other codes...
}

class hello{
public static void main(String[] args) {
    Demo demo=new Demo();
    System.out.println(demo.getClass().getName());
}
}

【运行结果】:Reflect.Demo

添加一句:所有类的对象其实都是Class的实例。

【案例2】实例化Class类对象

package Reflect;
class Demo{
//other codes...
}

class hello{
public static void main(String[] args) {
    Class<?> demo1=null;
    Class<?> demo2=null;
    Class<?> demo3=null;
    try{
        //一般尽量采用这种形式
        demo1=Class.forName("Reflect.Demo");
    }catch(Exception e){
        e.printStackTrace();
    }
    demo2=new Demo().getClass();
    demo3=Demo.class;

    System.out.println("类名称   "+demo1.getName());
    System.out.println("类名称   "+demo2.getName());
    System.out.println("类名称   "+demo3.getName());

}
}

【运行结果】:

类名称 Reflect.Demo

类名称 Reflect.Demo

类名称 Reflect.Demo

【案例3】通过Class实例化其他类的对象

通过无参构造实例化对象

package Reflect;

class Person{

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;
}
@Override
public String toString(){
    return "["+this.name+"  "+this.age+"]";
}
private String name;
private int age;
}

class hello{
public static void main(String[] args) {
    Class<?> demo=null;
    try{
        demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
        e.printStackTrace();
    }
    Person per=null;
    try {
        per=(Person)demo.newInstance();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    per.setName("Rollen");
    per.setAge(20);
    System.out.println(per);
}
}

【运行结果】:

[Rollen 20]

但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:

比如我定义了一个构造函数:

public Person(String name, int age) {
    this.age=age;
    this.name=name;
}

然后继续运行上面的程序,会出现:

java.lang.InstantiationException: Reflect.Person

at java.lang.Class.newInstance0(Class.java:340)

at java.lang.Class.newInstance(Class.java:308)

at Reflect.hello.main(hello.java:39)

Exception in thread "main" java.lang.NullPointerException

at Reflect.hello.main(hello.java:47)

所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数

【案例】通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)

package Reflect;

import java.lang.reflect.Constructor;

class Person{

public Person() {

}
public Person(String name){
    this.name=name;
}
public Person(int age){
    this.age=age;
}
public Person(String name, int age) {
    this.age=age;
    this.name=name;
}
public String getName() {
    return name;
}
public int getAge() {
    return age;
}
@Override
public String toString(){
    return "["+this.name+"  "+this.age+"]";
}
private String name;
private int age;
}

class hello{
public static void main(String[] args) {
    Class<?> demo=null;
    try{
        demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
        e.printStackTrace();
    }
    Person per1=null;
    Person per2=null;
    Person per3=null;
    Person per4=null;
    //取得全部的构造函数
    Constructor<?> cons[]=demo.getConstructors();
    try{
        per1=(Person)cons[0].newInstance();
        per2=(Person)cons[1].newInstance("Rollen");
        per3=(Person)cons[2].newInstance(20);
        per4=(Person)cons[3].newInstance("Rollen",20);
    }catch(Exception e){
        e.printStackTrace();
    }
    System.out.println(per1);
    System.out.println(per2);
    System.out.println(per3);
    System.out.println(per4);
}
}

【运行结果】:

[null 0]

[Rollen 0]

[null 20]

[Rollen 20]

【案例】 返回一个类实现的接口:

package Reflect;

interface China{
public static final String name="Rollen";
public static  int age=20;
public void sayChina();
public void sayHello(String name, int age);
}

class Person implements China{
public Person() {

}
public Person(String sex){
    this.sex=sex;
}
public String getSex() {
    return sex;
}
public void setSex(String sex) {
    this.sex = sex;
}
@Override
public void sayChina(){
    System.out.println("hello ,china");
}
@Override
public void sayHello(String name, int age){
    System.out.println(name+"  "+age);
}
private String sex;
}

class hello{
public static void main(String[] args) {
    Class<?> demo=null;
    try{
        demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
        e.printStackTrace();
    }
    //保存所有的接口
    Class<?> intes[]=demo.getInterfaces();
    for (int i = 0; i < intes.length; i++) {
        System.out.println("实现的接口   "+intes[i].getName());
    }
}
}

【运行结果】:

实现的接口 Reflect.China

(注意,以下几个例子,都会用到这个例子的Person类,所以为节省篇幅,此处不再粘贴Person的代码部分,只粘贴主类hello的代码)

【案例】:取得其他类中的父类

class hello{
public static void main(String[] args) {
    Class<?> demo=null;
    try{
        demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
        e.printStackTrace();
    }
    //取得父类
    Class<?> temp=demo.getSuperclass();
    System.out.println("继承的父类为:   "+temp.getName());
}
}

【运行结果】

继承的父类为: java.lang.Object

【案例】:获得其他类中的全部构造函数

class hello{
public static void main(String[] args) {
    Class<?> demo=null;
    try{
        demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
        e.printStackTrace();
    }
    Constructor<?>cons[]=demo.getConstructors();
    for (int i = 0; i < cons.length; i++) {
        System.out.println("构造方法:  "+cons[i]);
    }
}
}

【运行结果】:

构造方法: public Reflect.Person()

构造方法: public Reflect.Person(java.lang.String)

但是细心的读者会发现,上面的构造函数没有public 或者private这一类的修饰符

【案例】其实还可以通过反射调用其他类中的方法:

class hello {
public static void main(String[] args) {
    Class<?> demo = null;
    try {
        demo = Class.forName("Reflect.Person");
    } catch (Exception e) {
        e.printStackTrace();
    }
    try{
        //调用Person类中的sayChina方法
        Method method=demo.getMethod("sayChina");
        method.invoke(demo.newInstance());
        //调用Person的sayHello方法
        method=demo.getMethod("sayHello", String.class,int.class);
        method.invoke(demo.newInstance(),"Rollen",20);

    }catch (Exception e) {
        e.printStackTrace();
    }
}
}

【运行结果】:

hello ,china

Rollen 20

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值