天天看点

黑马程序员---java基础---反射机制

------- android培训、java培训、期待与您交流! ----------

一.反射:

 1.获取Class对象的三种方式:

  1).Object-->getClass():必须通过对象名调用;

  2).任何数据类型(包括基本数据类型)都有一个静态属性:class

  3).Class类的静态方法forName(String 全名限定的类名)

 2.通过Class对象,可以获取类中的:

  1).构造方法:

   --批量获取构造方法:

     public Constructor[] getConstructors():获取所有"公有"的构造方法

     public Constructor[] getDeclaredConstructors():获取所有的构造方法,包括私有、受保护、默认、公有

     --获取单个的构造方法,并调用:

      public Constructor getConstructor(Class ... parameterTypes):获取某个"公有"的构造方法

     public Constructor getDeclaredConstructor(Class ... parameterTypes):获取某个构造方法,包括私有、受保护、默认、公有

    调用某个构造方法:

     Constructor的newInstance()

例如:

package cn.itcast.demo02_通过Class对象获取构造方法;

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

/*
 * 通过Class对象可以获取类的:
 * 1.构造方法:
 * 2.成员属性:
 * 3.成员方法:
 * 
 * 1.获取构造方法:
 * 		--批量获取构造方法:
 *			public Constructor[] getConstructors():获取所有"公有"的构造方法
 *			public Constructor[] getDeclaredConstructors():获取所有的构造方法,包括私有、受保护、默认、公有
 * 		--获取单个的构造方法,并调用:
 * 			public Constructor getConstructor(Class ... parameterTypes):获取某个"公有"的构造方法
 *			public Constructor getDeclaredConstructor(Class ... parameterTypes):获取某个构造方法,包括私有、受保护、默认、公有
 *		调用某个构造方法:
 *			Constructor的newInstance()
 */
public class Demo {
	public static void main(String[] args) throws Exception {
		//1.加载Class对象
		Class stuClass = Class.forName("cn.itcast.demo02_通过Class对象获取构造方法.Student");
		//2.获取它内部所有的公有构造方法;
		Constructor[] conArray = stuClass.getConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		System.out.println("--------所有的构造方法,包括私有、受保护、默认-----------");
		conArray = stuClass.getDeclaredConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		System.out.println("---------获取公有、无参的构造方法,并调用---------------");
		Constructor con = stuClass.getConstructor();
		//调用此构造方法
		Object obj = con.newInstance();//会产生Student对象空间
		Student stu = (Student)obj;
		stu.show();
		System.out.println("---------获取公有、带参的构造方法,并调用---------------");
		con = stuClass.getConstructor(float.class);//指定调用公有的float参数的构造方法;
		obj = con.newInstance(3.5F);//传递实参
		
		System.out.println("-----------获取私有、带参的构造方法,并调用--------------");
		con = stuClass.getDeclaredConstructor(char.class);
		con.setAccessible(true);//暴力访问(会忽略访问修饰符)
		con.newInstance('男');
		
		System.out.println(con);
		
	}

}
           
package cn.itcast.demo02_通过Class对象获取构造方法;

public class Student {
	/**********构造方法************/
	public Student(){
		System.out.println("公有无参的构造方法");
	}
	public Student(float f){
		System.out.println("公有float参数的构造方法 : f = " + f);
	}
	protected Student(int n){
		System.out.println("受保护的int参数的构造方法:n = " + n);
	}
	Student(String s){
		System.out.println("(默认)的String参数的构造方法:s = " + s);
	}
	private Student(char c){
		System.out.println("(私有)的char参数的构造方法: c = " + c);
		
	}
	
	public void show(){
		System.out.println("我show......");
	}
}
           

  2).成员属性:

   --批量获取成员属性:

     public Field[] getFields():获取所有"公有"的成员属性

     public Field[] getDeclaredFields():获取所有的成员属性,包括私有、受保护、默认、公有

    --获取单个的成员属性,并调用:

      public Field getField(Class ... parameterTypes):获取某个"公有"的成员属性

     public Field getDeclaredField(Class ... parameterTypes):获取某个成员属性,包括私有、受保护、默认、公有

    为成员属性赋值:(要先实例化此类的对象)

     Field类的set(Object target,Object value)

例如:

package cn.itcast.demo03_通过Class对象获取成员属性;

import java.lang.reflect.Field;

/*
 * 通过Class对象获取成员属性:
 * 
 * 1.获取成员属性:
 * 		--批量获取成员属性:
 *			public Field[] getFields():获取所有"公有"的成员属性
 *			public Field[] getDeclaredFields():获取所有的成员属性,包括私有、受保护、默认、公有
 * 		--获取单个的成员属性,并调用:
 * 			public Field getField(Class ... parameterTypes):获取某个"公有"的成员属性
 *			public Field getDeclaredField(Class ... parameterTypes):获取某个成员属性,包括私有、受保护、默认、公有
 *		为成员属性赋值:
 *			Field类的set(Object target,Object value)
 *			
 */
public class Demo {
	public static void main(String[] args) throws Exception{
		Class stuClass = Class.forName("cn.itcast.demo03_通过Class对象获取成员属性.Student");
		System.out.println("------------获取所有公有的成员属性--------------");
		Field[] fieldArray = stuClass.getFields();
		for(Field f : fieldArray){
			System.out.println(f);
		}
		System.out.println("-----------获取所有的成员属性,包括私有--------------");
		fieldArray = stuClass.getDeclaredFields();
		for(Field f : fieldArray){
			System.out.println(f);
		}
		System.out.println("-----------获取公有成员,并赋值--------------");
		Field f = stuClass.getField("phoneNum");
		//要赋值,一定要先实例化一个此类的对象
		Object obj = stuClass.getConstructor().newInstance();//获取无参的构造方法,并调用
		f.set(obj, "18518151155");
		
		System.out.println("----------获取私有成员,并赋值----------------");
		f = stuClass.getDeclaredField("name");
		f.setAccessible(true);//设置暴力访问
		f.set(obj, "张三");
		//验证
		Student stu = (Student)obj;
		System.out.println("验证电话:" + stu.phoneNum);
		System.out.println("姓名:" + stu.getName());
		
	}
}
           
package cn.itcast.demo03_通过Class对象获取成员属性;

public class Student {
	//**************成员属性**************//
	private String name;
	int age;
	protected char sex;
	public String phoneNum;
	
	public String getName(){
		return this.name;
	}
}
           

  3).成员方法:

   --批量获取成员方法:

     public Method[] getMethods():获取所有"公有"的成员方法

     public Method[] getDeclaredMethods():获取所有的成员方法,包括私有、受保护、默认、公有

     --获取单个的成员方法,并调用:

      public Method getMethod(Class ... parameterTypes):获取某个"公有"的成员方法

     public Method getDeclaredMethod(Class ... parameterTypes):获取某个成员方法,包括私有、受保护、默认、公有

    调用成员方法:

     Method-->invoke(Object target,Object... args);

例如:

package cn.itcast.demo04_通过Class对象获取成员方法;

import java.lang.reflect.Method;

/*
 * 通过Class对象获取成员方法:
 * 
 * 1.获取成员方法:
 * 		--批量获取成员方法:
 *			public Method[] getMethods():获取所有"公有"的成员方法
 *			public Method[] getDeclaredMethods():获取所有的成员方法,包括私有、受保护、默认、公有
 * 		--获取单个的成员方法,并调用:
 * 			public Method getMethod(Class ... parameterTypes):获取某个"公有"的成员方法
 *			public Method getDeclaredMethod(Class ... parameterTypes):获取某个成员方法,包括私有、受保护、默认、公有
 *		调用成员方法:
 *			Method-->invoke(Object target,Object... args);
 *			
 */
public class Demo {
	public static void main(String[] args) throws Exception{
		Class stuClass = Class.forName("cn.itcast.demo04_通过Class对象获取成员方法.Student");
		
		System.out.println("-------------所有公有的成员方法--------------");
		Method[] methodArray = stuClass.getMethods();//包含父类的公有成员方法
		for(Method m : methodArray){
			System.out.println(m);
		}
		System.out.println("-------------所有的成员方法,包括私有的-----------");
		methodArray = stuClass.getDeclaredMethods();//不包含父类的;
		for(Method m : methodArray){
			System.out.println(m);
		}
		
		System.out.println("--------------获取某个公有的成员方法,并调用-----------");
		Method m = stuClass.getMethod("show", char.class);
		//先实例化一个Student对象
		Object obj = stuClass.getConstructor().newInstance();
		m.invoke(obj, '男');
		System.out.println("--------------获取某个私有的成员方法,并调用-----------");
		m = stuClass.getDeclaredMethod("show");
		m.setAccessible(true);//设置暴力访问
		m.invoke(obj);
		
		
	}
}
           
package cn.itcast.demo04_通过Class对象获取成员方法;

public class Student {
	private void show(){
		System.out.println("调用的是私有、无参的show()");
	}
	
	void show(int n){
		System.out.println("默认带参的show(int n)  n = " + n);
	}
	protected void show(String s){
		System.out.println("受保护带参的show(String s) s = " + s);
	}
	public void show(char c){
		System.out.println("公有带参的show(char c) c = " + c);
	}
}
           

二.设计模式:

 1.代理模式(动态代理):当我们需要调用某个方法是,需要在调用前,和调用做一些其他的事情,这时,我们可以为这个定义一个"代理类",在代理类中,重新定义"被代理类"中的方法,并添加新的内容。

Java中的动态代理:

 1.一般的代理模式,需要为原类增加"代理类",这样的话,代理类会越来越多;

 2.Java中的动态代理机制:

    1).自定义类,实现一个InvocationHandler接口;

            重写:invoke()方法;

    2).获取代理对象:

     Proxy类的静态方法:newProxyInstance():

     注意:Java中的动态代理是基于:接口的(要代理的类,必须是某个接口类型的子类)

 2.模板模式:

package cn.itcast.demo10_模板设计模式;
/*
 * 
 */
abstract class Person{
	//模板方法。此方法是由子类继承的;
	public void show(){
		System.out.println("大家好,我是一名 " + getType());
	}
	//需要子类实现的方法
	public abstract String getType();
}
class Student extends Person{
	public String getType(){
		return "学生";
	}
}
class Teacher extends Person{
	public String getType(){
		return "教师";
	}
}
public class Demo {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.show();
		
		Teacher tea = new Teacher();
		tea.show();
		
	}
}
           

 3.装饰模式:装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。