java笔记(八):反射

java中的反射,是指在运行时,对于任意一个类,都可以知道这个类的所有属性和方法,对于任意一个对象,都能调用该对象的所有属性和方法。

反射机制主要提供了如下功能,
在运行时:

  • 判断一个对象所属的类
  • 构造一个类的对象
  • 判定一个类的成员变量和方法
  • 调用一个对象的方法
  • 生成动态代理

判断一个对象所属的类

根据对象获取该类,或者根据类名获得该类的Class对象。

A t = new B();
Class c1 = t.getClass();
Class c2 = B.class;
Class c3 = null;
try {
    c3 = Class.forName("B");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
System.out.println(c1 == c2);  //true
System.out.println(c1 == c3);  //true
System.out.println(c1);  //class B

class A{}
class B extends A{}

判断该对象的父类和接口方法如下:

A t = new B();
Class c1 = t.getClass();

System.out.println(c1.getSuperclass());
System.out.println(c1.getInterfaces()[0]);

构造一个类的对象

首先需要获得该类的Class实例,然后通过newInstance()方法或者getConstructors()方法进行实例化。

//使用newInstance()赋值
try {
    Class classB = B.class;
    B b = (B)classB.newInstance();
    System.out.println(b.i);  //2
} catch(InstantiationException e){
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

class A{}
class B extends A implements I{
    public int i = 2;
}
//使用getConstructors()赋值
Class classB = B.class;
Constructor<?> cons[] = classB.getConstructors();

for (int i = 0; i < cons.length; i++) {
    Class<?> clazzs[] = cons[i].getParameterTypes();
    System.out.print("cons[" + i + "] (");
    for (int j = 0; j < clazzs.length; j++) {
        System.out.print(clazzs[j].getName()+"    ");
    }
    System.out.println(")");
}
//上述的输出结果如下:
//constructor [0]:(int    )
//constructor [1]:(int    int     )

try {
    B b = (B) cons[2].newInstance(3, 5);
    System.out.println(b.i);  //3
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

class A{}
class B extends A implements I{
    public int i = 2;
    public B(int i){
        this.i = i;
    }
    public B(int i, int j){
        this.i = i;
    }
}

两者的不同在于,前者是使用Class的newInstance()方法进行初始化,不带参数;后者使用Constructor的newInstance()方法进行初始化,可以带参数。
其中,第二个方法的代码使用了Constructor的getConstructors方法,该方法返回的是参数的类型。注意,参数的类型也是类,因此返回的参数类型是Class<T>

判定类的成员变量和方法

Class classA = A.class;
//输出属性
Field[] fields = classA.getFields();
for (Field field:fields ){
    Class type = field.getType();
    String prive = Modifier.toString(field.getModifiers());
    System.out.println(prive+" "+type.getName()+" "+field.getName());
}
//public java.lang.String i4
//public double i5
//输出方法
Method method[] = classA.getDeclaredMethods();
for (int i = 0; i < method.length; ++i) {
    Class<?> returnType = method[i].getReturnType();
    Class<?> para[] = method[i].getParameterTypes();
    int temp = method[i].getModifiers();
    System.out.print(Modifier.toString(temp) + " ");
    System.out.print(returnType.getName() + "  ");
    System.out.print(method[i].getName() + " ");
    System.out.print("(");
    for (int j = 0; j < para.length; ++j) {
        System.out.print(para[j].getName() + " " + "arg" + j);
        if (j < para.length - 1) {
            System.out.print(",");
        }
    }
    System.out.println(")");
}
//public java.lang.String  toString (java.lang.String arg0)
//public int  size ()
// void  eat (java.lang.String arg0)

class A{
    private int i1;
    protected Integer i2;
    int i3;
    public String i4;
    public double i5;
    public A(){}
    public int size(){return 0;}
    void eat(String s){
        System.out.println("eats");
    }
    public String toString(String name){
        System.out.println(name+":A");
        return name+"A";
    }
}

调用一个对象的方法

调用对象的方法和修改属性。即使属性是私有的,也可以修改。

Class classA = A.class;

Method m1 = classA.getDeclaredMethod("eat",String.class);
m1.invoke(classA.newInstance(), "rice");//eats rice

A a = (A) classA.newInstance();
Field i = classA.getDeclaredField("i1");
i.setAccessible(true);
i.set(a, 4);
System.out.println(i.get(a)); //4

class A{
    private int i1;
    public A(){}
    void eat(String s){
        System.out.println("eats "+s);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值