Java反射复习

三种实例化对象:

1、Class<?> cls = Class.forName("java.util.Date") ; ***
System.out.println(cls.getName());

2、类.class

3、对象.getClass
Class<?> cls = Class.forName("java.util.Date") ;
Object obj = cls.newInstance() ; // 实例化对象,等价于 new java.util.Date()  等价于  Date date  = new Date()
class Main{
    public static void main(String[] args) {
        System.out.println(new java.util.Date()==new java.util.Date());
        //false
    }
}
获得包名:
Class<?> cls = CLS.class ; // 取得Class类对象
System.out.println(cls.getPackage().getName());

获得父类接口:
Class<?> cls = CLS.class ; // 取得Class类对象
System.out.println(cls.getSuperclass().getName());
// 取得实现的父接口对象
Class<?>[] iClass = cls.getInterfaces() ;
for (Class<?> class1 : iClass) {
System.out.println(class1.getName());
}



获得构造方法:
Class<?> cls = Person.class ;
// 取得类中的全部构造
Constructor<?>[] constructors = cls.getConstructors() ;
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}



获取指定参数的构造:
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException

在定义简单java类的时候一定要保留有一个无参构造

Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class
类调用,只能够通过明确的构造调用实例化处理。

反射获得Date构造方法:

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

class Main{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException {
      Class<?> cls =   Class.forName("java.text.SimpleDateFormat");
        Constructor<?>[] constructor = cls.getConstructors();
        for (Constructor<?> constructor1 : constructor){
            System.out.println(constructor1);
        }

//        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//      String str = simpleDateFormat.format(new Date());
//        System.out.println(str);

        Constructor<?> cons = cls.getConstructor(String.class);
       System.out.println((SimpleDateFormat)cons.newInstance("yyyy-MM-dd HH:mm:ss"));
    }
}

反射获得指定参数构造方法

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Person {
    private String name ;
    private int age ;
    public Person(String name,int age) {
        this.name = name ;
        this.age = age ;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}
class Test {
    public static void main(String[] args) throws InstantiationException,
            IllegalAccessException, NoSuchMethodException, SecurityException,
            IllegalArgumentException, InvocationTargetException {
        Class<?> cls = Person.class;
// 取得指定参数类型的构造方法对象
        Constructor<?> cons = cls.getConstructor(String.class, int.class);
        System.out.println(cons.newInstance("yuisama", 29));
    }
}
public Method[] getMethods() throws SecurityException


public Method getMethod(String name, Class<?>... parameterTypes)


public static void main(String[] args) throws Exception {
Class<?> cls = Person.class ;
Method[] methods = cls.getMethods() ;
for (Method method : methods) {
System.out.println(method);
}
}
import java.lang.reflect.Method;
class Person {
private String name ;
private int age ;
public Person() {}
public Person(String name,int age) {
this.name = name ;
this.age = age ;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + 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 class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.java.hhy.Person") ;
// 任何时候调用类中的普通方法都必须有实例化对象
Object obj = cls.newInstance() ;
// 取得setName这个方法的实例化对象,设置方法名称与参数类型
Method setMethod = cls.getMethod("setName", String.class) ;
// 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
// 同时传入参数
setMethod.invoke(obj, "yuisama") ; // 相当于Person对象.setName("yuisama") ;
Method getMethod = cls.getMethod("getName") ;
Object result = getMethod.invoke(obj) ; // 相当于Person对象.getName() ;
System.out.println(result) ;
  }
}

此类操作的好处是:不再局限于某一具体类型的对象,而是可以通过Object类型进行所有类的方法调用

---------------------------------------------------------    属性的获取
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.bit.java.testthread.Student") ;
{ // 普通代码
// 第一组-取得父类中全部属性
Field[] fields = cls.getFields() ;
for (Field field : fields) {
System.out.println(field) ;
}
}
System.out.println("------------------------");
{
// 第二组-取得类中全部属性
Field[] fields = cls.getDeclaredFields() ;
for (Field field : fields) {
System.out.println(field);
}
}
}
}
package www.bit.java.testthread;
import java.lang.reflect.Field;
class Person {
private String name ;
}
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.bit.java.testthread.Person") ;
// 实例化本类对象
Object obj = cls.newInstance() ;
// 操作name属性
Field nameField = cls.getDeclaredField("name") ;
nameField.set(obj, "yuisama") ; // 相当于对象.name = "yuisama"
System.out.println(nameField.get(obj)); // 取得属性
}
}

自定义类加载器
cls.getClassLoader() = AppClassLoader(应用程序类加载器)
cls.getClassLoader().getParent()) = ExtClassLoader(扩展类加载器);
最顶层: Bootstrap(启动类加载器): 启动类加载器无法被Java程序直接引用。
-------------------------------------------------------------------
双亲委派模型:

我们的应用程序都是由这三种加载器互相配合进行加载的,如果有必要,还可以加入自定义的类加载器。
双亲委派模型要求除了顶层的父类加
载器外,其余的类加载器都应有自己的父类加载器。
双亲委派模型的工作流程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这
个请求委托给父类加载器去完成,每一个层次的类加载器都是如此。因此,所有的加载请求都应当传送到顶层的
BootStrap加载器中,只有当父加载器反馈无法完成这个加载请求时(在自己搜索范围中没有找到此类),子加载器
才会尝试自己去加载。
类加载器的双亲委派模型从JDK1.2引入后被广泛应用于之后几乎所有的Java程序中,但它并不是强制性约束,甚至
可以破坏双亲委派模型来进行类加载,最典型的就是OSGI技术。
双亲委派模式对于保证Java程序的稳定运行很重要。有一个显而易见的好处就是Java类随着它的类加载器一起具备
了一种带有优先级的层次关系。例如java.lang.Object类,它存放在rt.jar中,无论哪一个类加载器要加载这个类,
最终都是委派给处于顶端的启动类加载器进行加载。因此,Object类在程序的各种类加载器环境中都是同一个类

 

比较两个类相等的前提:必须是由同一个类加载器加载的前提下才有意义。否则,即使两个类来源于同一个Class
文件,被同一个虚拟机加载,只要加载他们的类加载器不同,那么这两个类注定不想等。

动态代理模式

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface ISubject { // 核心操作接口
public void eat(String msg, int num) ; // 吃饭是核心业务
}
class RealSubject implements ISubject {
@Override
public void eat(String msg ,int num) {
System.out.println("我要吃 "+num + "分量的 "+msg) ;
}
}
/**
* 动态代理类
*/
class ProxySubject implements InvocationHandler {
// 绑定任意接口的对象,使用Object描述
private Object target ;
/**
* 实现真实对象的绑定处理,同时返回代理对象
* @param target
* @return 返回一个代理对象(这个对象是根据接口定义动态创建生成的代理对象)
*/
public Object bind(Object target) {
// 保存真实主题对象
this.target = target ;
return
Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfac
es(),this) ;
}
public void preHandle() {
System.out.println("[ProxySubject] 方法处理前") ;
}
public void afterHandle(){
System.out.println("[ProxySubject] 方法处理后") ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.preHandle() ;
// 反射调用方法
Object ret = method.invoke(this.target,args) ;
this.afterHandle() ;
return ret;
}
}
public class TestDemo {
public static void main(String[] args) {
ISubject subject =(ISubject) new ProxySubject().bind(new RealSubject()) ;
subject.eat("宫保鸡丁",20) ;
}
}
原文地址:https://www.cnblogs.com/hetaoyuan/p/11409554.html