您的位置:首页 > 职场人生

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

2013-12-06 18:38 381 查看
----------------------
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: