java-反射


1,构造方法的反射

package javaBase.reflect;

import java.lang.reflect.Constructor;

/*
 * 三种获取字节码对应的实例对象(Class类型)的方法:
 * 九种预定义的 Class 对象,表示八个基本类型和 void
 * boolean、byte、char、short、int、long、float、 double。 
 * 源程序中出现的类型,都有各自的Class实例对象:int[] ,void  .....
 */
public class Test1 {
	public static void main(String[] args) throws Exception{
		String str1 = "haha";
		Class cls1 = str1.getClass();
		Class cls2 = String.class;
		Class cls3 = Class.forName("java.lang.String");//详细
		System.out.println(cls1 == cls2);//true
		System.out.println(cls1 == cls3);//true
		//判断一个类是不是基本数据类型:
		System.out.println(cls1.isPrimitive());//false
		System.out.println(int.class.isPrimitive());//true
		System.out.println(int.class==Integer.class);//Integer是包装类,false
		System.out.println(int.class == Integer.TYPE);//type:包装的源数据类型  true
		System.out.println(int[].class.isPrimitive());//数组也是一个类型,不是原始类型
		System.out.println(int[].class.isArray());
		
		//Constructor类代表某个类中的一个构造方法
		Constructor c1 = String.class.getConstructor(StringBuffer.class);
//		用反射实现:String s1  = new String(new StringBuffer("abc"));
		String str2 = (String)c1.newInstance(new StringBuffer("abc"));
		//编译时:不会执行等号赋值,只检查语法,看定义,所以不知道c1是个什么对象的构造方法
		System.out.println(str2.charAt(2));
		
	}
	//反射就是将java类中的各种成分映射成相应的java类
}

2,成员变量的反射

package javaBase.reflect;
//反射就是将java类中的各种成分映射成相应的java类
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/*
 * 三种获取字节码对应的实例对象(Class类型)的方法:
 * 九种预定义的 Class 对象,表示八个基本类型和 void
 * boolean、byte、char、short、int、long、float、 double。 
 * 源程序中出现的类型,都有各自的Class实例对象:int[] ,void  .....
 */
public class Test1 {
	public static void main(String[] args) throws Exception{
		String str1 = "haha";
		Class cls1 = str1.getClass();
		Class cls2 = String.class;
		Class cls3 = Class.forName("java.lang.String");//详细
		System.out.println(cls1 == cls2);//true
		System.out.println(cls1 == cls3);//true
		//判断一个类是不是基本数据类型:
		System.out.println(cls1.isPrimitive());//false
		System.out.println(int.class.isPrimitive());//true
		System.out.println(int.class==Integer.class);//Integer是包装类,false
		System.out.println(int.class == Integer.TYPE);//type:包装的源数据类型  true
		System.out.println(int[].class.isPrimitive());//数组也是一个类型,不是原始类型
		System.out.println(int[].class.isArray());
		
		//Constructor类代表某个类中的一个构造方法
		Constructor c1 = String.class.getConstructor(StringBuffer.class);
//		用反射实现:String s1  = new String(new StringBuffer("abc"));
		String str2 = (String)c1.newInstance(new StringBuffer("abc"));
		//编译时:不会执行等号赋值,只检查语法,看定义,所以不知道c1是个什么对象的构造方法
		System.out.println(str2.charAt(2));
		
		Point p = new Point(3, 5);
		//fieldY是类的,不是具体对象的。用它去取某个具体对象上对应的值
		Field fieldY = p.getClass().getField("y");//y是类的字段名
		System.out.println(fieldY.get(p));
//		Field fieldX = p.getClass().getField("x");//找不到,x是private
		Field  fieldX = p.getClass().getDeclaredField("x");//可以看见了,但是不能取
		fieldX.setAccessible(true);//暴力反射
		System.out.println(fieldX.get(p));
		changeStringValue(p);
		System.out.println(p);
	}
	/*
	 * 将一个对象中的String类型成员变量的值中“b”改成“a”
	 */
	private static void changeStringValue(Point p) throws Exception {
		Field[] fields = p.getClass().getFields();
		for(Field f:fields){
			if(f.getType()==String.class){//字节码只有一份,用==比较,而不用equals()
				String oldValue = (String)f.get(p);//获取成员变量值
				String newValue = oldValue.replace("b", "a");
				f.set(p, newValue);//成员变量重新赋值
			}
		}

	}
	
}

附:Point类

package javaBase.reflect;

public class Point {
	private int x;
	public int y;
	public String str1 = "ball";
	public String str2 = "bascketball";
	public String str3 = "it";
	public Point(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	@Override
	public String toString() {
		return str1+": "+str2+": "+ str3;
	}
}

3成员方法的反射

		//Method 例子:charAt()
		Method mCharAt = String.class.getMethod("charAt", int.class);
		char ch = (Character)mCharAt.invoke(str1, 1);//invoke调用.str1这里为null是静态方法
		System.out.println(ch);

 4,main()方法反射

<span style="white-space:pre">		</span>new DoMain().main(new String[]{"111","222","333"});
		//main()方法,不知道类的名字,只知道到时候传过来要调用其main方法
		String someClassName = args[0];//传入类名(带包)
		Method mainMethod = 
				Class.forName(someClassName).getMethod("main", String[].class);
		mainMethod.invoke(null, (Object)new String[]{"111","222","333"});//静态方法用null
		/*
		 * jdk1.4把数组当成n个参数,jdk1.5把数组当做一个参数,为了兼容1.4:
		 * java5会自动把数组弄成多个单独参数
		 * 这两种方法都可以避免数组被拆成几个参数
		 */
		
		mainMethod.invoke(null, new Object []{new String[]{"111","222","333"}});

5,数组的反射

package javaBase.reflect;

import java.lang.reflect.Array;
/*
 * 数组的反射
 */
public class ArrayReflect {
	public static void main(String[] args) {
		int[] a1 = new int[3];
		int[] a2 = new int[4];
		int[][] a3 = new int[2][3];
		String[] s = new String[3];
		System.out.println(int.class.getSuperclass());//null,基本类型没有父类?
		System.out.println(a1.getClass()==a2.getClass());//true维度,类型相同
//		System.out.println(a1.getClass() == a3.getClass());
//		System.out.println(a1.getClass() == s.getClass());
		System.out.println(a1.getClass().getName());//类名:[I
		System.out.println(a1.getClass().getSuperclass().getName());//obj
		System.out.println(a3.getClass().getName());//[[I
		System.out.println(s.getClass().getSuperclass().getName());//obj
		
		Object o1 = a1;
		Object o2 = a3;
		Object o3 = s;
//		Object[] o4 = a1;//基本数据类型数组不是Object[];整个数组是一个Object对象
		Object[] o5 = s;
		Object[] o6 = a3;//降低了维度
		
		String[] strings = new String[]{"a","b","c"};
		printObj(strings);
		printObj("haha");
	}
	/*
	 * 数组的反射类:Array
	 */
	private static void printObj(Object obj) {
		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);
		}
		
	}

}

6,反射与框架,通过配置文件创建对象

package javaBase.reflect;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;

/*
 * 当一个对象存储到hashset中后,就不要修改那些参与计算哈希值的字段了
 * 否则修改后的对象hashcode值与存入时不同,导致不能找到这个对象和单独删除该对象导致内存泄露
 */
public class ReflectTest {
	public static void main(String[] args) throws Exception {
		InputStream in = new FileInputStream("config.properties");
		Properties prop = new Properties();
		prop.load(in);
		in.close();//关闭资源:当前操作系统的窗口或者什么为其提供资源的对象
		//用反射建立集合
		String className = prop.getProperty("className");
		Collection c = (Collection)Class.forName(className).newInstance();
//		Collection c = new HashSet();
		Point p1 = new Point(3, 3);
		Point p2 = new Point(5, 5);
		Point p3 = new Point(3, 3);
		c.add(p1);
		c.add(p2);
		c.add(p3);
		c.add(p1);
//		p1.y = 7;
		c.remove(p1);//上面这句执行后会导致remove()找不到p1,从而不能删除
		System.out.println(c.size());
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值