Java基础加强之反射


/*反射的基石:Class类


 *Java程序中各个Java类属于同一类事物描述这类事物的Java类名就是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());
        	
        	
        }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值