黑马程序员-张孝祥老师高新技术-反射学习总结

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

jdk1.5新特性
 * 1、静态导入
 * import static java.lang.Math.*; 
 * 2、可变参数
 * 出现在参数列表的最后,例如:fun(int a,int ... b)
            在jdk1.4中将可变参数封装为数组的形式
 * 3、增强for循环
 * enhanced for
 * 例如:
 * for(类型      变量名 : 集合变量名)
 * {
 *    System.out.println(变量名);
 * }
 * 注意:集合变量可以是数组或是实现了Iterable接口的集合类
 * 4、基本数据类型的自动拆箱和装箱
 * Integer num = 12;装箱
 * System.out.println(num+12);拆箱
 * 享元模式:flyweight
 * 如果有很多很小的对象,它们有很多属性相同,就可以把它们变成一个对象,那些不同的属性,作为方法的参数传送,称作外部状态,那些相同的属性,称作这个对象的内部状态。
 
overload----override区别
重载
重写
方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重写Overriding是父类与子类之间多态性的一种表现,
重载Overloading是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。
子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

反射就是把Java类中的各种成分映射成相应的Java类。
* Java类的组成:成员变量,方法,构造方法,包等。
* Java中的class类提供一系列的方法来获取Java类中的变量,方法,构造方法,修饰符,包等信息,
* 这些信息就是用相应类的实例对象;来表示,它们是Field、Method、Constructor、package等。

 * 创建类的实例对象的步骤:
 * class-->Constructor-->object

得到字节码文件的方法有三种:(得到字节码对应的实例对象,Class类型)
1、类名.class   例如 System.class
2、对象.getClass()  例如 new Date().getClass()
3、Class.forName("类名"),例如 Class.forName("java.util.Date")

* 分析反射的原理
* 反射就是把Java类中的各种成分映射成相应的Java类。
* Java类的组成:成员变量,方法,构造方法,包等。
* Java中的class类提供一系列的方法来获取Java类中的变量,方法,构造方法,修饰符,包等信息,
        * 这些信息就是用相应类的实例对象来表示,它们是Field、Method、Constructor、package等。
 * 
 * Constructor类代表某个类中的一个构造方法
 * 得到某个类的所有构造方法
 * 例如:Constructor[] ct = Class.forName("java.lang.String").getConstructors();
 * 得到某一个构造方法
 * 例子:Constructor ct1 = Class.forName("java.lang.String").getConstructors(StringBuffer.class);
 * 创建实例对象
 * 通常方式   :String str = new String(new StringBuilder("abc"));
 * 反射方式:String str1 = (String)Constructor.newInstance(new StringBuffer("abc"));
 * 
 * Field类代表某个类中的一个成员变量.
 * 得到的Field是对应到类上面的成员变量,不是对应到对象上面的成员变量。类只有一个,但是实例对象可以有多个。
 * 
 * Mehtod类代表某个类中的一个成员方法
 * 得到类中的某一个方法
 * 例如:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class) 
 * 调用方法:
 * 通常方式:System.out.println(str.charAt(1));
 * 反射方式:System.out.println(charAt.invoke(str,1));
 * 
 * 用反射方式执行某个类的main方法。
 * 写一个程序,它可以根据用户提供的类名,去执行该类中的main方法。
 * 因为jdk1.5兼容JDK1.4,使用反射方式调用可以是编译器做特殊处理,不会把参数当作数组看待,也就不会将数组打散成若干个参数了。
 * 
 * 数组反射
 * 具有相同维数和元素类型的数组属于同一个类型,即具有相同的class实例对象
 * 代表数组的class实例对象的getSuperClass()方法返回的父类为Object类对应的class.
 * 基本类型的一维数组可以被当作Object类型使用,不能当作object[]类型使用,非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用
 * Arrays.asList()方法处理int[]和string[]时的差异
 * Arrays工具类用于完成对数组的反射操作。

反射演示,代码如下:

package com.itheima.day25;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
 * 创建类的实例对象的步骤:
 * class-->Constructor-->object
 * 
 * Constructor类代表某个类中的一个构造方法
 * 得到某个类的所有构造方法
 * 例如:Constructor[] ct = Class.forName("java.lang.String").getConstructors();
 * 得到某一个构造方法
 * 例子:Constructor ct1 = Class.forName("java.lang.String").getConstructors(StringBuffer.class);
 * 创建实例对象
 * 通常方式   :String str = new String(new StringBuilder("abc"));
 * 反射方式:String str1 = (String)Constructor.newInstance(new StringBuffer("abc"));
 * 
 * Field类代表某个类中的一个成员变量.
 * 得到的Field是对应到类上面的成员变量,不是对应到对象上面的成员变量。类只有一个,但是实例对象可以有多个。
 * 
 * Mehtod类代表某个类中的一个成员方法
 * 得到类中的某一个方法
 * 例如:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class) 
 * 调用方法:
 * 通常方式:System.out.println(str.charAt(1));	
 * 反射方式:System.out.println(charAt.invoke(str,1));
 * 
 * 用反射方式执行某个类的main方法。
 * 写一个程序,它可以根据用户提供的类名,去执行该类中的main方法。
 * 因为jdk1.5兼容JDK1.4,使用反射方式调用可以是编译器做特殊处理,不会把参数当作数组看待,也就不会将数组打散成若干个参数了。
 * 
 * 数组反射
 * 具有相同维数和元素类型的数组属于同一个类型,即具有相同的class实例对象
 * 代表数组的class实例对象的getSuperClass()方法返回的父类为Object类对应的class.
 * 基本类型的一维数组可以被当作Object类型使用,不能当作object[]类型使用,非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用
 * Arrays.asList()方法处理int[]和string[]时的差异
 * Arrays工具类用于完成对数组的反射操作
 * 
 * 
 */
public class ReflectConstructor 
{
	public static void main(String[] args) throws Exception
	{
		String.class.getConstructors();//获取String类的所有构造函数
		Constructor cs = String.class.getConstructor(StringBuffer.class);//获取某一个构造函数
		System.out.println(cs);
		
		Class<String> cs1 = String.class.getConstructor().getDeclaringClass();//通过构造类获取对象的类名
		System.out.println(cs1);
		
		Constructor cs3 = String.class.getConstructor(StringBuffer.class);//得到构造方法
		String str1 = (String) cs3.newInstance(new StringBuffer("abc"));//这里的StringBuffer要和上面的一致
		System.out.println(str1.charAt(2));
		//创建实例对象
		//通常方式   :String str = new String(new StringBuilder("abc"));
		//反射方式:String str1 = (String)Constructor.newInstance(new StringBuffer("abc"));
		
		//反射成员变量
		ReflectPoint pt1 = new ReflectPoint(3,5);
		Field fieldy = pt1.getClass().getField("y");//getField()只可以得到公有的(可见的),而不可以得到私有的成员变量
		//fieldy不是对象身上的变量,而是类上字节码的变量,要用他去取某个对象上对应的值
		System.out.println("fieldy="+fieldy.get(pt1));
		//暴力反射,私有成员也可以获取
		Field fieldx = pt1.getClass().getDeclaredField("x");//获取不可见的var
		fieldx.setAccessible(true);//设置私有成员也可访问
		System.out.println("fieldx="+fieldx.get(pt1));
		
		changeStringValue(pt1);
		System.out.println(pt1);
		
		//method反射
		//str.charAt(1)
		String str = "abc";
		Method methodCharAt = String.class.getMethod("charAt", int.class);
		System.out.println("method="+methodCharAt.invoke(str, 1));//invoke调用,如果此处第一个参数str是null,则该方法是一个静态方法
		
		//调用主方法
		//TestArguments.main(new String[]{"1243","234"});//一般方法,利用静态代码的方式直接调用main方法
		String StartingClassName = args[0];
		Method mainMethod = Class.forName(StartingClassName).getMethod("main", String[].class);
		mainMethod.invoke(null,new Object[] {new String[]{"111","222","333"}});
		//mainMethod.invoke(null,(Object){new String[]{"111","222","333"}});这种写法也可以
		
        //数组反射		
		//int[] a1 = new int[3];
		int[] a1 = new int[]{1,3,5};//如果给数组初始化了就不可以给她指定个数
		int[] a2 = new int[4];
		int[][] a3 = new int[2][3];
		//String[] a4 = new String[3];	
		String[] a4 = new String[]{"a","b","c"};	
		System.out.println(a1.getClass() == a2.getClass());
		System.out.println(a1.getClass().getName());//获取类名
		System.out.println(a1.getClass().getSuperclass().getName());//获取父类的类名
		Object obja1 = a1;
		Object obja2 = a4;
		Object[] obja3 = a3;//一维数组可以看成一个Object,二维数组就可以看成一个一维数组中装一个object(一维数组)
		
		System.out.println(a1);
		System.out.println(a4);//打印数组哈希值
		System.out.println(Arrays.asList(a1));
		System.out.println(Arrays.asList(a4));//直接打印出数组值
		
		Object obj =null;
		printObject(a4);
		printObject("xyz");
		
	}
    //打印Object对象,包括数组
	private static void printObject(Object obj) {
        Class clazz = obj.getClass();
        if(clazz.isArray())
        {
        	int len = Array.getLength(obj);
        	for(int x=0;x<len;x++)
        	{
        		System.out.println(Array.get(obj, x));
        	}
        }
        else
        	System.out.println(obj);
	}
    //通过反射修改类中的变量值
	private static void changeStringValue(Object obj) throws Exception {
		Field[] f = obj.getClass().getFields();
		for (Field fd : f) {
			if (fd.getType() == String.class) {
				String oldValue = (String) fd.get(obj);
				String newValue = oldValue.replace('b', 'a');
				fd.set(obj, newValue);
			}
		}
	}
}
class TestArguments
{

	public static void main(String[] args)
	{
		for(String s : args)
		{
			System.out.println(s);
		}
	}
}

package com.itheima.day25;

public class ReflectPoint {

	/**
	 * 
	 * 成员变量的反射
	 * variable
	 * 
	 * @param args
	 */
        //通过field反射获得传递的x和y的值
		private int x;
		public int y;
		//利用反射将字符串中的b换成a
		public String str1 = "ball";
		public String str2 = "basketball";
		public String str3 = "itcast";
		public ReflectPoint(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}
		@Override
		public String toString()
		{
			return str1+":"+str2+":"+str3;
		}
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + x;
			result = prime * result + y;
			return result;
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ReflectPoint other = (ReflectPoint) obj;
			if (x != other.x)
				return false;
			if (y != other.y)
				return false;
			return true;
		}
		

}

--------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

                                           详细请查看:http://edu.csdn.net

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值