java核心技术10阅读(三)-继承(toString方法重写)

反射
能够分析类能力的程序叫做反射
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. 不要过多使用反射,功能对于编写系统程序来说极其实用,但是通常不适于编写应用程序,很多错误是在运行中产生的。

发布了15 篇原创文章 · 获赞 1 · 访问量 134

猜你喜欢

转载自blog.csdn.net/qq_17236715/article/details/103757308
今日推荐