Java基础知识陷阱(四)

本文发表于本人博客

今天我们来说说关于java继承以及反射有关的问题,大家先看下下面代码,试问可以编译通过不,为什么具体说说原因?

public class Test{
        public static void main(String[] args){
            Person p = new Man();
            p.talk();
        }
    }

    class Person{
        public void talk() throw NullPointerException{
            System.out.println("Person is talking");
        }
    }

    class Man extends Person{
        protected void talk() throw Exception{
            System.out.println("Man is talking");
        }
    }

  

如果平时多留意的话估计这个问题显而易见了是存在问题的,这个是提问关于继承中Override父类的方法。

我 们知道要想实现override必须要返回类型,方法名称,参数列表一致才能符合是override,但是这其中还有一些规则需要注意,比如访问级别、异 常抛出。上面的代码是无法编译通过的,其中存在2个问题:一是子类重写父类方法的时候访问级别必须是大于等于父类的访问的级别;二是子类重写父类方法的时 候异常范围必须是小于等于父类异常的范围。上面的代码稍微修改下就可以了,把protected改成public,异常Eception改成 NullPointerException这样就符合了编译就通过了!当然也可以稍微改下(反过来)代码如下:

class Person{
    protected void talk() throws Exception{
        System.out.println("Person is talking");
    }
}
class Man extends Person{
    public void talk() throws NullPointerException{
        System.out.println("Man is talking");
    }
}

子类的talk方法的访问级别public大于等于父类talk方法的访问级别,子类的talk方法的异常NullPointerException小于等于父类talk方法的异常Exception。

下面来问问可以修改下面Demo类中的name成员吗,可以的话用什么方法来实现?

class Demo{
    private String name = "hello";

    public int age ;

    public String GetName(){
        return name;
    }
    public int GetAge(){
        return age;
    }

}

这 个问题大家知道其实就是问的反射,在java里面类中的所有成员包括public、private在反射面前都是可以无效的,是不是觉得这个反射太强大了 啊!我们可以使用以下方法来实现修改字段:1.通过类的.class的语法;2.通过类对象的getClass()方法;3.通过Class对象的 forName()方法。

看代码name字段是属于私有的字段,那么我们看使用getField()方法吗,查看下jdk帮助文档就可以得出它只是返回的public成员并不能返 回私有的,那私有的怎么得到这时我们可以使用getDeclaredField()方法不过要记住,要用setAccessible(true)修改其访 问属性不然是报错的,现在看看下面代码我们怎么来修改私有字段和公有字段的:

    public static void main(String[] args) throws Exception {
        Demo d = new Demo();
        Class<?> cl = Demo.class;

        //这个是可以返回私有,getField(name)只是public成员
        Field namefield = cl.getDeclaredField("name");
        //不要忘记修改其访问属性
        namefield.setAccessible(true);
        namefield.set(d,"world");

        Field agefield = cl.getField("age");
        agefield.set(d,30);

        System.out.println(d.GetName());
        System.out.println(d.GetAge());
    }

我们执行代码,就可以看到输出的结果了是我们预期的了。

world
30

这次先到这里。坚持记录点点滴滴!

时间: 2024-11-03 07:31:45

Java基础知识陷阱(四)的相关文章

Java基础知识陷阱系列

Java基础知识陷阱系列 今天抽空把Java基础知识陷阱有关的文章汇总于此,便于大家查看. Java基础知识陷阱(一) Java基础知识陷阱(二) Java基础知识陷阱(三) Java基础知识陷阱(四) Java基础知识陷阱(五) Java基础知识陷阱(六) Java基础知识陷阱(七) Java基础知识陷阱(八)

Java基础知识陷阱(九)

本文发表于本人博客. 今天我来说说关于JAVA多线程知识,有错误请指出.大家都知道JAVA在服务端上处理也有很大优势,很多公司也有在服务器跑JAVA进程,这说明JAVA在处理这个多线程以及并发下也有一定有优点的(这说法有点坑了).下面来看看 那java中,不具备直接操作像操作系统一样的PV信号,然而它提供了synchronized来实现同步机制,可能这样说不够严谨.JAVA的基类Object中有以下几个方法: public final native void notify(); public f

Java基础知识陷阱(十)

上个星期由于时间比较紧所以未能继续写下去,今天再接再厉,专心 + 坚持这样离目标就越来越近了!废话少说说正题,今天我们还是来说说java中比较基础的知识,大家知道编写java程序中很多时候都用到了xml文件,有 些是框架本身支持配置的,有些是自定义配置的,这样就要求我们要对这个xml原理要比较了解,其中加载xml文件转换节点元素时有个核心:递归调用转换. 我们可以通过下面方法来查查这个实现类有关的源码: 1 2 3 4 DocumentBuilderFactory factory = Docum

java基础知识拾遗(四)

1.Runnable对象 启动线程:(new Thread(new MyRunnable()).start() 2.jsp中<%@ page language="java" import="java.util.*" errorPage="error.jsp" isErrorPage="false" %>  改页面不能使用exception对象 3.枚举 enum AccountType { SAVING, FIXE

Java基础知识陷阱(三)

本文发表于本人博客. 之前都讲了有关字符串的陷阱,那今天来说下关于静态这个东西,这分为静态变量.静态方法,先看下面的代码请问结果输出是什么?: class Person01{ private static Person01 person = new Person01(); public static int age; public static int hight = 0; private Person01(){ age++; hight++; } public static Person01

Java基础知识陷阱(七)

本文发表于本人博客. 上次说了下HashSet和HashMap之间的关系,其中HashMap这个内部有这么一句: static final float DEFAULT_LOAD_FACTOR = 0.75f; 这一句表示一个常量,作用是当容器数量大小达到0.75%的时候就进行重新在构建一个2倍大小的数组.竟然这2个是集合,那我们今天看看其他的集合类,比如:ArrayList.Vector.LinkedList,开始咯. 首先查看下ArrayList的源码,这几个集合类都是在java.util包下

Java基础知识陷阱(六)

本文发表于本人博客. 上次说了下equals跟==的问题,今天再来认识一下这个equals()跟hasCode().上次的代码如下: class Person{ public String name; public Person(String name){ this.name = name; } public String getName(){ return this.name; } @Override public boolean equals(Object anObject) { if (t

Java基础知识陷阱(一)

本文发表于本人博客. 事隔好多年了,重新拿起来Java这门语言,看似熟悉其实还很陌生,想想应该梳理下顺便提高下自己.这次先来看看Java里面的String这个对象. 经典的先看下面一段代码,请问最终创建几个对象,分别在哪里? String s0 = new String("luoliang.me"); String s1 = "luoliang.me"; String s2 = new String("luoliang.me"); 想要回答这个问

Java基础知识陷阱(五)

本文发表于本人博客. 今天我来说说关于静态变量初始化.数组.==与equals的问题,看下面代码: public class Test{ private final int age; private String name; public Test(){ age = 30; } public Test(String name){ this.name = name; } } 我想上面的代码好多人都知道了会编译报错的,原因是在代餐构造函数中未对age进行复制操作. 对于终态变量final程序中是可以