java反射机制高级应用-基本操作

2019-03-03  本文已影响0人  这个人的昵称有点酷

反射概述

三种方式调用Class类(反射源头)

  1. Object类的getClass()方法,判断两个对象是否是同一个字节码文件
//判断是否是同一个字节码对象
//Person p = new Person();
Class clazz = p.getClass();

面试题:请解释Object类中的所有方法以及每一个方法使用上的注意事项:

  1. 静态属性Class,锁对象(Hiberate)
//当作静态方法的锁对象 
//Person.class
Class clazz = Person.class
  1. Class类中静态方法forName(),读取配置文件
//读取配置文件
//Person.java
Class clazz = class.forName("类全限定名");

利用反射实例化对象

package cn.jishuz.demo;
class Student{
    public Student() {
        System.out.println("Student类的构造方法");
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Student类的toString()方法";
    }
}
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> cls = Class.forName("cn.jishuz.demo.Student");
        // 相当于关键字new实例化对象,等价:Object obj = new Object();
        Object obj = cls.newInstance();
        System.out.println(obj);
    }
}

++必须要求类中存在无参构造方法,否则报错: <font color="red">java.lang.InstantiationException<font>++

操作构造方法

可以解决上面实例化必须要无参构造的现象

在Class类里面定义了可以取得一个类之中构造方法的操作:

package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Student{
    private String name;
    private Integer age;
    public Student(String name,Integer age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "姓名:"+ this.name+",年龄:"+this.age;
    }
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("cn.jishuz.demo.Student");
        Constructor<?> cons = cls.getConstructor(String.class,Integer.class);
        // 相当于关键字new实例化对象,等价:Object obj = new Object();
//      Object obj = cls.newInstance();
        Object obj = cons.newInstance("TOM",20);
        System.out.println(obj);
    }
}

调用类中方法

取得了类的实例化对象后就可以开始调用类中的方法。

两种类型:

- 取得父类继承而来的方法:

1.取得全部方法:

public Method[] getMethods()
                    throws SecurityException

2.获取指定方法:

public Method getMethod(String name,Class<?>... parameterTypes)
                 throws NoSuchMethodException, SecurityException
- 取得本类定义的方法:

1.取得全部方法:

public Method[] getDeclaredMethods()
                            throws SecurityException

2.获取指定方法

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
                         throws NoSuchMethodException, SecurityException

范例:

package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

interface Message{
    public void get();
}

class Student implements Message{
    @Override
    public void get() {}
    public void fun(){}
    public void print(){}
    
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("cn.jishuz.demo.Student");
        Method met[] = cls.getMethods();
        for(int x= 0;x<met.length;x++){
            System.out.println(met[x].getName());
        }
    }
}
============运行结果=============
get
print
fun
wait
wait
wait
hashCode
getClass
equals
toString
notify
notifyAll

其它

取得方法修饰符:public int getModifiers();


取得方法的返回参数类型:public Class<?> getReturnType();


取得方法的参数:public Class<?>[] getParameterTypes();


取得所有抛出的异常:public Class<?>[] getExceptionTypes()


++反射调用类中的方法++:public Object invoke(Object obj,Object... args)

调用类中的属性(尽量不要去使用)

支持的方法有两类:

  1. 取得所有继承而来的属性:
  1. 取得本类定义的属性:
package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

interface Message{
    public static final String INFO = "hello world.";
}
class Person{
    private String name;
    private Integer age;
}
class Student extends Person implements Message{
    private String school;
    private Double price;
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("cn.jishuz.demo.Student");
        {//取得继承而来的全部属性
            Field fields[] = cls.getFields();
            for(int x= 0;x<fields.length;x++){
                System.out.println(fields[x]);
            }
            System.out.println("------------");
        }
        {//取得本类定义的全部属性
            Field fields[] = cls.getDeclaredFields();
            for(int x= 0;x<fields.length;x++){
                System.out.println(fields[x]);
            }
            System.out.println("------------");
        }
        {//取得父类属性
            Field fields[] = cls.getSuperclass().getDeclaredFields();
            for(int x=0;x<fields.length;x++){
                System.out.println(fields[x]);
            }
        }
    }
}
============运行结果=============
public static final java.lang.String cn.jishuz.demo.Message.INFO
------------
private java.lang.String cn.jishuz.demo.Student.school
private java.lang.Double cn.jishuz.demo.Student.price
------------
private java.lang.String cn.jishuz.demo.Person.name
private java.lang.Integer cn.jishuz.demo.Person.age

在Field类里面还定义有进行属性调用的方法:

在Constrcutor、Method、Field三个类上有一个共同的父类AccessibleObject,在这个类里面定义了可以取消封装的方法:public void etAccessible(boolean flag);设置成true即可取消封装。


觉得还行可以点个星星哦

上一篇 下一篇

猜你喜欢

热点阅读