Equals、ToString、反射

Equals方法

    Object类中的equals方法用于检测一个对象是否等于另一个对象。在Object类中,这个方法将判断两个对象是否具有相同的引用,如果有相同引用,那么它们一定的相等的。但一般,我们经常需要检测两个对象的状态(值)是否相等,单纯判断两个对象是否相等意义不大,下面是一个完美的equals方法:

    1.参数为otherObject

    2.if(this == otherObject) return true;

    3.if(otherObject == null) return false;

    4.if(getClass() != otherObject.getClass()) return false;

    5.if(!(otherObject instanceOf ClassName)) return false;

    6.将otherObject转换为相应的类型

           ClassName other = (ClassName)otherObject;

    7.现在开始对要比较的域进行比较了,基本类型用==比较,对象用equals比较。

Equals与hashCode的定义必须一致,如果a.equals(b) return true;那么a.hashCode 必须与 b.hashCode有相同的值。

 

ToString方法:

    Object中的重要方法,返回对象的字符串值,下面是toString的通用方法(java核心技术引用)

public class ObjectAnalyzer {
	private ArrayList<Object> visited = new ArrayList<Object>();

	public String toString(Object obj) {
		if (obj == null)
			return "null";
		if (visited.contains(obj))
			return "...";
		visited.add(obj);
		Class cl = obj.getClass();
		if (cl == String.class)
			return (String) obj;
		if (cl.isArray()) {
			String r = cl.getComponentType() + "[]{";
			for (int i = 0; i < Array.getLength(obj); i++) {
				if (i > 0)
					r += ",";
				Object val = Array.get(obj, i);
				if (cl.getComponentType().isPrimitive())//是否是基本类型
					r += val;
				else
					r += toString(val);
			}
			return r + "}";
		}

		String r = cl.getName();
		do {
			r += "[";
			Field[] fields = cl.getDeclaredFields();
			AccessibleObject.setAccessible(fields, true);//可以访问对象的私有域
			for (Field f : fields) {
				if (!Modifier.isStatic(f.getModifiers())) {
					if (!r.endsWith("["))
						r += ",";
					r += f.getName() + "=";
					try {
						Class t = f.getType();
						Object val = f.get(obj);					
						if (t.isPrimitive())
							r += val;
						else
							r += toString(val);
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
			}
			r += "]";
			cl = cl.getSuperclass();
		} while (cl != null);

		return r;
	}
}

 

反射:

    1.在运行中分析类的能力

    2.在运行中查看对象

    3.实现数组的操作代码

    4.利用Method对象

    5.查看类的结构等等

一.Class类

   1. Class类保存每个对象所属的 足迹

Object o2 = new ArrayReflect();
Class o = ArrayReflect.class;
System.out.println(o == o2.getClass()); 

    结果 :true

   2. 获得Class类的三种方式

    (1)

Object obj1 = new Object();
Class cl1 = obj1.getClass();

    (2)

Class cl2 = Class.forName(" java.lang.Object");

    一般forName与newInstance配合使用,创建一个对象

Object object = Class.forName(" java.lang.Object").newInstance();

 

    (3)一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类

Class cl3 = Object.class;
Class cl4 = int.class;
Class cl5 = Object[].class;

    3.利用反射分析类的能力

        java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的域、方法、构造器。三个类中都有getName方法,用于返回项目的名称;getModifiers方法,返回一个整型数值,用于描述public和static这样的修饰符的使用状况,可以用Modifier.toString(f.getModifiers()),来分析整型数值的情况。

       Calss类中的getFields、getMethods、getConstructors方法将分析返回类提供的public域 、方法和构造器数组,其中包括父类的公有成员 。Class类中的getDeclaredFields、getConstructors、getDeclaredMethods方法将分析返回类中的全部域 、方法和构造器,其中包括private、protected成员,但是不包括父类的成员

       下面是输出类中全部域名,构造器和方法的代码:

	public static void main(String[] args) {
		try {
			Class cl = Class.forName("java.lang.Double");
			String modifiers = Modifier.toString(cl.getModifiers());
			System.out.println("modifiers = " + modifiers);//修饰符
			System.out.println("name = " + cl.getName());//名称
			System.out.println("super name = " + cl.getSuperclass().getName());//父类名称
			System.out.println();
			// 域
			Field[] field = cl.getDeclaredFields();
			for (Field f : field) {
				System.out.println("field modifiers = "
						+ Modifier.toString(f.getModifiers()));//修饰符
				System.out.println("field type = " + f.getType());//类型
				System.out.println("field name = " + f.getName());//名称
			}
			System.out.println();
			
			// 构造器
			Constructor[] constructor = cl.getConstructors();

			for (Constructor c : constructor) {
				System.out.println("constructor modifiers = "
						+ Modifier.toString(c.getModifiers()));//修饰符
				System.out.println("constructor name = " + c.getName());//名称

				Class[] params = c.getParameterTypes();
				for (Class p : params) {
					System.out.println("constructor paramsName = "
							+ p.getName());//参数
				}
			}
			System.out.println();
			
			// 方法
			Method[] method = cl.getDeclaredMethods();

			for (Method m : method) {
				System.out.println("method modifiers = "
						+ Modifier.toString(m.getModifiers()));//修饰符
				System.out.println("method returnType = " + m.getReturnType());//返回类型
				System.out.println("method name = " + m.getName());//名称
				Class[] methodParams = m.getParameterTypes();
				for (Class mp : methodParams) {
					System.out.println("method params = " + mp.getName());//参数
				}
			}

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
    
 

    4.在运行时使用反射分析对象
       利用反射,在运行进访问私有域,AccessibleObject.setAccessible(数组, true); 使用java程序不受到安全管理器的控制,这样就可以访问private的内容了

public class Test {
	public static void main(String[] args) throws SecurityException,
			NoSuchFieldException, IllegalArgumentException,
			IllegalAccessException {
		ReflectA reflectA = new ReflectA("张三", 10);
		Class cl = reflectA.getClass();
		Field[] field = cl.getDeclaredFields();
		// 使用java程序不受到安全管理器的控制,这样就可以访问private的内容了
		AccessibleObject.setAccessible(field, true);
		for (Field f : field) {
			if ("name".equals(f.getName())) {
				Object obj = f.get(reflectA);
				System.out.println("obj:" + obj.toString());
			}
		}

	}
}

public class ReflectA {
	private String name;
	public int age;
	public static String address;

	public ReflectA(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void hello() {
		System.out.println("hello~~~~");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
   

     5.通用的数组扩展长度方法

public class ArrayReflect {

       public Object arrayGrow(Object t) {
		// 返回值声明为Object类型,而不声明为对象型数组Object[],基本类型数组可以转换成Object,但不能转换成对象数组。
		Class cl = t.getClass();
		if (!cl.isArray())
			return null;
		// 基本类型
		Class componentType = cl.getComponentType();
		int length = Array.getLength(t);
		int newLength = length + 10;
		// 构造新数组,componentType数组类型,newLength新数组长度
		Object newArray = Array.newInstance(componentType, newLength);
		// arraycopy方法可以扩展任意类型的数组,不仅是对象数组
		System.arraycopy(t, 0, newArray, 0, length);
		return newArray;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Object o2 = new ArrayReflect();
		Class o = ArrayReflect.class;
		System.out.println(o == o2.getClass());
		// TODO Auto-generated method stub
		int[] oldArray = { 1, 2, 3, 4, 5 };

		Object newArray = new ArrayReflect().arrayGrow(oldArray);
		System.out.print(newArray.getClass().getComponentType().getName()
				+ "[" + Array.getLength(newArray) + "] = {");
		for (int i = 0; i < Array.getLength(newArray); i++) {
			System.out.print(Array.get(newArray, i) + " ");
		}
		System.out.println("}");
		
	}
}

结果:
    int[15] = {1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值