/*反射的基石:Class类
*Class类代表Java类,它的各个实例对象分别对应各个类在内存中的的字节码对象
package cn.baidu.com;
import java.lang.reflect.*;
import java.util.Arrays;
public class ReflectText {
public static void main(String[] args) throws Exception {
String str1="abc";
Class cls1=str1.getClass();//第一种方式获取字节码对象
Class cls2=String.class;//第二种方式
Class cls3=Class.forName("java.lang.String");//第三种方式
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println();
System.out.println(cls1.isPrimitive());//是否是基本类型
System.out.println(int.class.isPrimitive());
System.out.println(int.class==Integer.class);
System.out.println(int.class==Integer.TYPE);
System.out.println(int[].class.isPrimitive());
什么是反射:反射就是把Java类中的各种成分映射成相应的java类
表示java类的Class类要提供一系列的方法来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,
他们是Field,Method,Contruntor,Package等等
1.Constructor类代表某个类中的一个构造方法
Constructor constructor=String.class.getConstructor(StringBuffer.class);//得到一个构造方法
String str2=(String)constructor.newInstance(new StringBuffer("abc"));//反射方式创建实例对象
System.out.println(str2.charAt(2));
2.Field类
package cn.baidu.com;
public class Reflectpoint {
private int x;
public int y;
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;
}
public String toString()
{
return str1+":"+str2+":"+str3;
}
}
Reflectpoint pt1=new Reflectpoint(3,5);
//fieldY的值是多少?fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
Field fieldY=pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));
Field fieldX=pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
//changStringValue(pt1);
//System.out.print(pt1);
System.out.println();
3.Method类:代表某个类中的一个成员方法
如果传递给Method对象的invoke()方法的一个参数为nuil,这说明该Method对象对应的是一个静态方法
Method methodCharAt=String.class.getMethod("charAt", int.class);//获取字节码对象中的charAt方法
System.out.println(methodCharAt.invoke(str1, 1));//invoke:方法对象身上的方法
System.out.println(methodCharAt.invoke(str1,new Object[]{2}));
//--------------用反射方式执行某个类中的main方法---------------
写一个程序,能够根据用户提供的类名,去执行该类中的main方法
class TestArguments
{
public static void main(String[] args) {
for(String arg:args)
{
System.out.println(arg);
}
}
}
//1.普通方式:TestArguments.main(new String[]{"222","333","444"});
//2.反射方式:
String startingClassName="cn.baidu.com.TestArguments";
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"});//这里注意java会自带拆箱,加上Object防止其拆箱
//---------------数组的反射----------------------------------------------
//具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
//代表数组的Class实例对象的getSuperClass()方法返回父类为Object类对应的Class
//基本类型的一维数组可以被当做Object类型使用,不能当Object[]使用
int[] a1=new int[]{1,2,3};
int[] a2=new int[4];
int[][] a3=new int[3][4];
String[] a4=new String[]{"a","b","c"};
System.out.println(a1.getClass()==a2.getClass());
//System.out.println(a1.getClass()==a3.getClass());//不是同一个类型
//System.out.println(a1.getClass()==a4.getClass());
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
Object aObj1=a1;
Object aObj2=a4;
Object[] aObj3=a3;
Object[] aObj4=a4;
//Object[] aObj5=a1; 基本类型不能当Object[]使用
System.out.println(a1);
System.out.println(a4);
//Object.asList()接收的是一个Object[]类型的参数,而a1被作为了一个Object类型
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
printObject(a1);
printObject("xyz");
}
private static void printObject(Object obj) {//拆包,把Object类型数组拆成一个个元素
Class clazz=obj.getClass();
if(clazz.isArray())
{
int len=Array.getLength(obj);
for(int i=0;i<len;i++)
{
System.out.println(Array.get(obj, i));
}
}
else
System.out.println(obj);
}
private static void changStringValue(Object obj) throws Exception//把字符串中的b,改成 a
{
Field[] fields=obj.getClass().getFields();//获取该类的字节码对象的所有字段
for(Field field:fields)//遍历所有字段
{
if(field.getType()==String.class)//如果字段的类型是String类型
{
String oldValue=(String)field.get(obj);
String newValue=oldValue.replace('b', 'a');
field.set(obj,newValue);
}
}
}
//-----------------------------反射的作用,实现框架功能--------------------------------------------
1.框架与工具类的区别:工具类被用户调用,而框架则是调用用户提供的类
2.之前写好的框架如何调用你以后写的类?因为在写程序时无法知道要被调用的类名,因此,
在程序中无法直接new某个类的实例对象,这时就要用反射方式来做
package cn.baidu.com;
import java.util.*;
import java.io.*;
public class ReflectText2
{
public static void main(String[] args) throws Exception
{
InputStream ips=new FileInputStream("config.properties");//在配置文件config.properties中写明ArrayList或HashtSet的完整类名
properties props=new properties();
props.load(ips);
ips.close();
String className=props.getProperty("className");
Collection collections=(Collection)Class.forName(className).newInstance();
//Collection collections=new ArrayList();
//Collection collections=new HastSet();
Reflectpoint pt1=new Reflectpoint(3,3);
Reflectpoint pt2=new Reflectpoint(5,5);
Reflectpoint pt3=new Reflectpoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
//pt1.y=7;
//collections.remove(pt1);
System.out.println(collections.size());
}
}