A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵太云 中级黑马   /  2013-7-13 16:30  /  1162 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 赵太云 于 2013-7-15 10:26 编辑

    protected修饰符不是同一个包或不同包的子类可以访问吗?
   以下这个方法是Object类中的方法:
       为什么Object的子类不可以调用这个方法????
        public class  Test {
            public static void main(String[] args) throws Exception {
                    new String("赵太云").clone();//报错了!
                      new String("赵太云").finalize();//报错了!
           }
      }

[size=-1]protected  void
finalize()
          当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。


[size=-1]protected  Object
clone()
          创建并返回此对象的一个副本。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
clone(),finalize() 不是String里的public 方法,你看下源码它的修饰是什么情况。。在java 目录下有其源码,这两个之所以是protected 修饰符就是
因为很多类都不需要这两个方法暴露出来  根据封装的特点 就将它隐藏起来,不让调用者使用 以免发生错误。 而且clone()的方法在我看来很诡异
其实现细节我见过  如果我没记错   实现是如下的  return (MyClass)super.clone();   它的源码是C语言实现的 java native interface JNI的东西,这些
如果是基础我建议不涉及。。。。。
回复 使用道具 举报
zhou5852 发表于 2013-7-13 17:36
clone(),finalize() 不是String里的public 方法,你看下源码它的修饰是什么情况。。在java 目录下有其源码 ...

可是protected修饰的不是可以被子类对象调用?这个怎么就不能调用?
回复 使用道具 举报
看我细细给你分析,你的       new String("赵太云").clone();//报错了!与new String("赵太云").finalize();//报错了! 是写在 类Test里吧 很明显你的Test里没有复写过那两个函数, 如果你想在这个类中调用函数 就需要用super 关键字吧。 这是一点。(不理解可以跳过这点  看完后面的理解后再看前面的)
第二点,你在类中的main方法中 以new 的方式 形成了字符串对象。而finalize()方法是调用 对象中的方法吧。
你认为String 既然继承了Object  所以它的对象都能调用这个函数,但是你要注意 你这个对象调用这个函数时  这个函数所在的类 并未在 java.lang 包中 也就是说 你的Test 类与String类不在同一个包中,所以你无法通过它的对象调用其中protected函数,若在同包中是可以的。    还有一种方法就是说String 的子类中可以调用那两个函数是吧,是的它的子类中可以调用 但是很可以 String 是final类型的  它不支持子类拓展。
你若想调用这个函数   你在Test类中 就需要建立个非静态方法 才能调用 、不过调用后就是过过眼瘾,能编译通过的 main主函数写上一句Hello可以输出
至于为什么main函数里就不能 使用super调用了  是因为main是静态的,静态的方法中不允许使用一些非静态的值或者方法,具体原因需要了解类加载原理后就知道了
代码如下
  1. package org.openscience.zhoubo;

  2. public class Test {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub

  8.         }
  9.         public void fun() throws Throwable {
  10.                 super.finalize();
  11.                 super.clone();
  12.         }

  13. }
复制代码

评分

参与人数 1技术分 +2 收起 理由
神之梦 + 2 很给力!

查看全部评分

回复 使用道具 举报
zhou5852 发表于 2013-7-13 20:35
看我细细给你分析,你的       new String("赵太云").clone();//报错了!与new String("赵太云").finalize( ...

似懂非懂。。。。。。
回复 使用道具 举报
赵太云 发表于 2013-7-15 10:24
似懂非懂。。。。。。

:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L:L
回复 使用道具 举报
本帖最后由 longlangcx 于 2013-7-15 13:27 编辑

这俩方法被protected修饰,相当于只在本包或子类中才能访问。就好像private一样,你自定义一个Test类,可以使用对象名.方法名的形式访问其他类的对象的private方法么?不可以。。那么你自定义了一个Test类,自然也不可以访问其他对象的protected方法。道理一样,权限不够。想访问String的clone方法,除非是子类,可是String类时final的不可继承,那么除非你把你的Test类丢到java.lang软件包中,否则无法访问String的clone方法。String的clone方法只有他自己的方法才可以调用。

至于为啥要这样设计呢?道理很简单,一个对象在哪里存活的好好的,突然不知道从哪里来个家伙调用了这个对象的finalize()方法,他不就挂了么~?咋死的都不知道!这当然不怎么合理。

至于clone方法也是一样,啥是clone,创建一个原对象的副本,等于是创建了一个新的对象。但不是每个对象都希望无关人员可以克隆自己的。
还记得单例设计模式么?就是为了对象的唯一性。要是clone方法是public的话,那我Singleton.getInstance().clone(),等于创建了一个单例的副本,那这个类不就相当于有俩对象了么~?

也就是说,通常情况下,你不见得希望别人可以创建你对象的副本,或者随意调用你的对象的finalize()方法,那么默认的protected就保证了这一点。
如果,你确实有需要把这两个方法暴露出来,覆盖它并声明为public就好了。
回复 使用道具 举报
查看了下protected这个修饰符:
    能在同一个包中使用。
    能在子类中使用。
    我2b了。。。。。。。{:soso_e136:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马