反射
能够分析类能力的程序叫做反射
java运行时,会为每一个对象加入一个运行类class,实际上是一种类型。java虚拟机可以处理它,通过getclass、object.class以及Class.forName(“xxx”)的方式得到这个class。其次也可以通过newInstance()的方式来实例化对象。
try catch 捕获异常。
可以利用反射类输出所有类的信息包括(域,构造函数,方法等),公有可以用get获得,而如果要查看私有域或者私有方法等,可以利用setAccessible 方法,将域设置成可访问的。
利用反射机制重写toString方法,查看任意对象的内部信息,并且监听和修改
jdk1.8以上反射修改对象会有警告
public String toString(Object obj){
if(obj == null) return "null";
if(visited.contains(obj)) return "...";
else visited.add(obj);
Class cl = obj.getClass();
if(cl == String.class) return (String) obj;
if(cl.isArray()){
String res = cl.getComponentType() + "[]{";
for(int i = 0; i < Array.getLength(obj); i++)
{
if(i > 0) res += ",";
Object val = Array.get(obj, i);
if(cl.getComponentType().isPrimitive()) res += val;
else res += toString(val);
}
return res + "}";
}
String res = cl.getName();
//inspect the fields of this class and all superclasses
do{
res += "[";
Field[] fields = cl.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
//get name and values
for(Field ele : fields){
//filter the static variable
if(!Modifier.isStatic(ele.getModifiers()))
{
if(!res.toString().endsWith("[")) res += ",";
res += ele.getName() + "=";
//identify the primitive and object
try
{
Class t = ele.getType();
Object val = ele.get(obj);
if(t.isPrimitive()) res += val;
else res += toString(val);
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
}
res += "]";
cl = cl.getSuperclass();
}
while (cl != null);
return res;
}
**继承设计技巧**
1. 公共操作和域放在超类中
2. 不要使用proteced受保护域,一是因为子类的的访问破环了封装性,二是因为同一个包中所有的类都能方位受保护域。***protected在同一个包中和public相同,子类能继承,在不同类中子类和父类都能访问。而在不同包中,子类和父类都不能访问。**
3. 利用is-a去判断是否使用继承
4. 除非所有继承的方法都有意义, 否则不要使用继承
5. 在覆盖方法时, 不要改变预期的行为
6. **使用多态,而非类型判断。可以减少代码,并且让代码易于维护。**
7. 不要过多使用反射,功能对于编写系统程序来说极其实用,但是通常不适于编写应用程序,很多错误是在运行中产生的。