Java学习--day05

2021/9/22 20:44:10

本文主要是介绍Java学习--day05,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

反射

  • 反射机制:通过一个抽象的类名能在自己记忆(加载类的内存)中找到匹配的类的具体信息。
//理解class类并实例化Class类对象
Person p = new Person();
//实例化Class类对象的四种方法
Class c = Person.class;//通过类的class属性获取,最为安全可靠,程序性能最高
Class c1 = p.getClass();//通过某个类的实例获取
try {
    Class c2 = Class.forName("day13.Person");//通过Class的静态方法forname来获取一个类的class实例,常用方法
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
//        ClassLoader cl =  this.getClass().getClassLoader();
//        try {
//            Class c3 = cl.loadClass("day13.Person");
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//运行时创建对象并获取类的完整结构:
//获得父类
  Class superclass = c.getSuperclass();
  System.out.println("父类:"+superclass.getName());

//获得接口
  Class[] interfaces = c.getInterfaces();
  for (Class c1 : interfaces) {
      System.out.println("接口"+c1.getName());
  }

//获得构造器
  Class c = Class.forName("day13.Person");
  Constructor[] con = c.getConstructors();//获取公有的构造器
  for (Constructor con1 :con){
      System.out.println("构造方法名"+con1.getName());
      System.out.println("构造方法修饰符为"+con1.getModifiers());

      Class[] c2 = con1.getParameterTypes();
      for(Class clazz :c2){
          System.out.println(clazz);
      }
      System.out.println("--------------");
  }
  Constructor[] con2 = c.getDeclaredConstructors();//获取所有构造器
  for (Constructor con3 :con2){
      System.out.println("构造方法名"+con3.getName());
      System.out.println("构造方法修饰符为"+con3.getModifiers());

      Class[] c3 = con3.getParameterTypes();
      for(Class clazz1 :c3){
          System.out.println(clazz1);
      }
      System.out.println("--------------");
  }

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

//创建对象
  Class clazz = Class.forName("day13.Student");
  Object obj = clazz.newInstance();//相当于调用无参构造
  Student s = (Student) obj;
  System.out.println(s.school);

  Constructor c = clazz.getConstructor(String.class);//调用一个参数的构造
  Student stu = (Student)c.newInstance("张三");
  System.out.println(stu.name);

  Constructor c = clazz.getDeclaredConstructor(String.class,String.class);//调用两个参数的构造
  c.setAccessible(true);//解除私有的封装,下面就可以对这个私有方法强制使用
  Student stu = (Student) c.newInstance("李四","希望小学");
  System.out.println(stu.name+stu.school);

//获得方法
  Method[] ms = clazz.getDeclaredMethods();//获取类的所有方法
  for(Method m : ms){
  System.out.println("方法的名称"+m.getName());
  System.out.println("方法的修饰符"+m.getModifiers());
  System.out.println("返回值的类型"+m.getReturnType());

  Class[] cl = m.getParameterTypes();
  if(cl != null && cl.length > 0){
      for(Class c : cl){
          System.out.println("参数类型"+c.getName());
      }
  }
  System.out.println("------------");
  }

//获得属性
  //Field[] f= clazz.getFields();//获得公有的
  Field[] f= clazz.getDeclaredFields();//获得所有的
  for (Field f1 : f) {
      System.out.println("属性的名称"+f1.getName());
      System.out.println("属性的修饰符"+f1.getModifiers());
      System.out.println("属性的类型"+f1.getType());
      System.out.println("---------");
  }

//获得包名
  Package p = clazz.getPackage();
  System.out.println(p.getName());
  
//通过反射调用类的指定方法、指定属性
//指定方法
Constructor c = clazz.getConstructor(String.class);
Object obj = c.newInstance("张三");
Method m = clazz.getMethod("setInfo", String.class, String.class);
m.invoke(obj,"张三","希望小学");
Method m1 = clazz.getDeclaredMethod("test",String.class);
m1.setAccessible(true);//解除私有封装,下面可以调用
m1.invoke(obj,"张三");
//调用有返回值的方法
Method m2 = clazz.getMethod("getSchool");
String s = (String)m2.invoke(obj);
System.out.println(s);

//指定属性
Constructor con = clazz.getConstructor(String.class);
Student s = (Student) con.newInstance("沙城一小");

Field f = clazz.getField("school");
f.set(s,"希望小学");
System.out.println(f.get(s));

Field f1 = clazz.getDeclaredField("privateField");//访问私有
f1.setAccessible(true);
f1.set(s,"1");
System.out.println(f1.get(s));
  • 动态代理
//1.创建一个实现接口的InvocationHandel的类,它必须实现invoke方法,以完成代理的具体操作。
public class ProxyDemo implements InvocationHandler {
	Object obj;
	 public ProxyDemo(Object obj){
        this.obj =obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      System.out.println(method.getName()+"方法开始执行");

      Object result = method.invoke(this.obj,args);//执行的是指定的代理对象的指定的方法

      System.out.println(method.getName()+"方法执行完毕");
      return result;
    }
}
//2.创建被代理的类以及接口
public class TestDemoImp1 implements ITestDemo{
    @Override
    public void test1() {
        System.out.println("执行test1");
    }

    @Override
    public void test2() {
        System.out.println("执行test2");
    }

    @Override
    public void test3() {
        System.out.println("执行test3");
    }
}

public interface ITestDemo {
    void test1();
    void test2();
    void test3();
}

//3.通过Proxy的静态方法newProxyInstance(ClassLoader Loader,Class[] interfaces,InvocationHandler h)创建一个Subject接口代理。
  ITestDemo t = new TestDemoImp1();
  InvocationHandler handler = new ProxyDemo(t);
  /**
    * 第一个参数是代理对象的类加载器
    * 第二个参数是代理对象的接口
    * 第三个参数是代理对象
    * 返回的值是成功被代理后对象,返回的是Object类型
    */
	ITestDemo t1 =(ITestDemo)Proxy.newProxyInstance(handler.getClass().getClassLoader(),t.getClass().getInterfaces(),handler);
  /**
    * 如果一个代理类想要被 Proxy.newProxyInstance方式代理那么这个对象的类一定要有对应的接口
    * 就像本例中的接口ITestDemo和实现类TestDemoImp1一样
    */

//4.通过Subject代理调用RealSubject实现类的方法。
  t1.test1();
  t1.test2();
  t1.test3();


这篇关于Java学习--day05的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程