精华内容
下载资源
问答
  • 举例子,列数字,作比较,打比方,这几个说明方法的例句
    千次阅读
    2020-12-21 14:01:13

    举例子,列数字,作比较,打比方,这几个说明方法的例句

    2018-09-19

    推荐内容

    点击登录

    举例子,列数字,作比较,打比方,这几个说明方法的例句

    来自 Clarence 的提问

    最佳答案

    由提问者推荐

    常见的说明方法有举事例、分类别、列数据、作比较、画图表、下定义、作诠释、打比方、摹状貌、引资料等10种。写说明文要根据说明对象的特点及写作目的,选用最佳方法。下面分别加以说明。

    (1)举例子。举出实际事例来说明事物,使所要说明的事物具体化,以便读者理解,这种说明方法叫举例法。如:

    一般人总以为,年龄稍大,记忆能力就一定要差,其实不然,请看实验结果:国际语言学会曾对9至18岁的青年与35岁以上的成年人学习世界语作过一个比较,发现前者就不如后者的记忆力好。这是因为成年人的知识、经验比较丰富,容易在已有的知识基础上,建立广泛的联系。这种联系,心理学上称为“联想”。人的记忆就是以联想为基础的,知识经验越丰富,越容易建立联想,记忆力就会相应提高。马克思五十多岁时开始学俄文,六个月后,他就能津津有味地阅读著名诗人与作家普希金、果戈里和谢德林等人的原文著作了。这是由于语言知识丰富,能够通晓很多现代和古代的语言的缘故。

    这段文章要说明的是:年龄稍大,记忆力不一定就差。为了说明这一点,作者先提供了实验结果,又分析了原因。到此为止,未尝不可,但不够具体,也缺乏说服力,于是,又举出了一个实例:马克思在五十多岁的时候,只用六个月时间便精通了俄语。这样一来,内容具体了,说服力增强了。

    说明文中的举事例的说明方法和议论文中的例证法,都可以起到使内容具体、加强说服力的作用。但二者又有区别。议论文中的事例,是用来证明观点的,说明文的事例,是用来介绍知识的。

    运用举事例的说明方法说明事物或事理,一要注意例子的代表性,二要注意例子的适量性。

    (2)分类别。将被说明的对象,按照一定的标准划分成不同的类别,一类一类地加以说明,这种说明方法,叫分类别。

    分类别是将复杂的事物说清楚的重要方法。

    运用分类别方法要注意分类的标准,一次分类只能用同一个标准,以免产生重叠交叉的现象。例如:“图书馆的藏书有中国的、古典的、外国的、科技的、文学的、现代的以及政治经济方面的等。”这里用了不只一个标准,所以表达不清。正确的说法应该是:

    图书馆的藏书,按国别分,有中国的、外国的;按时代分,有古典的、现代的;按性质分,有科技的、文学的以及政治经济方面的等。

    这样,每次分类只用一个标准,就眉目清楚了。

    有的事物的特征、本质需要分成几点或几个方面来说,也属于分类别。

    注意,运用分类别方法,所列举的种类不能有遗漏。

    (3)列数据。为了使所要说明的事物具体化,还可以采用列数据的方法,以便读者理解。需要注意的是,引用的数字,一定要准确无误,不准确的数字绝对不能用,即使是估计的数字,也要有可靠的根据,并力求近似。

    (4)作比较。说明某些抽象的或者是人们比较陌生的事物,可以用具体的或者大家已经熟悉的事物和它比较,使读者通过比较得到具体而鲜明的印象。事物的特征也往往在比较中显现出来。

    在作比较的时候,可以是同类相比,也可以是异类相比,可以对事物进行“横比”,也可以对事物进行“纵比”。

    (5)画图表。为了把复杂的事物说清楚,还可以采用图表法,来弥补单用文字表达的缺欠,对有些事物解说更直接、更具体。

    (6)下定义。用简明的语言对某一概念的本质特征作规定性的说明叫下定义。下定义能准确揭示事物的本质,是科技说明文常用的方法。

    下定义的时候,可以根据说明的目的需要,从不同的角度考虑。有的着重说明特性,如关于“人”的定义;有的着重说明作用,如关于“肥料”的定义;有的既说明特性又说明作用,如关于“统筹方法”和“应用科学”的定义。

    ①人是能制造工具并使用工具进行劳动的高级动物。

    ②肥料是能供给养分使植物生长的物质。

    ③统筹方法,是一种安排工作进程的数学方法。

    ④工程技术的科学叫做应用科学,它是应用自然科学的基础理论来解决生产实践中出现的问题的学问。

    冰山

    2009-08-30

    0

    59

    21

    其他5条回答

    其他回答

    5条回答

    fujiyue

    2009-08-30

    列数字

    南浦大桥是上海市区第一座跨越黄浦江的大桥,建成于1991年11月。总长8346米,其中主桥全长846米,引桥全长7500米。

    作比较

    李白想落天外的特点,大大发展了庄子寓言,屈原初次的浪漫精神和表现手法,也融汇了道教的神仙意象,具有令人惊叹不已的艺术魅力,赢得了一代「诗仙」的赞誉。而杜甫是中国文学史上伟大的现实主义诗人,他的诗深刻地反映了唐朝由兴盛走向衰亡时期的社会面貌,具有丰富的社会内容,鲜明的时代色彩和强烈的政治倾向。他的诗激荡着热爱祖国、热爱人民的炽烈情感和不惜自我牺牲的崇高精神,因此被后人公认为“诗史”。

    举例子

    艺术手法方面的显著特点,比如,李白的诗歌在艺术手法方面的显著特点是:想象神奇,变化无端,结构纵横跳跃,句式长短错落,形成了雄奇飘逸的风格。

    0

    4

    5

    天宇

    2009-09-08

    中国人说话爱打比方,用于文章叫比喻。比方打得好,可以生动形象、通晓 明白,帮助人们理解问题,所以好的演讲者都会打比方。但是,如果比方打得不好,或者说打得太“好”,那就令人厌恶了。

    打比方是向别人——尤其是外行,解释一个问题的良好方法。很多学者和管理专家都愿意采用打比方的方式来说明一个问题。但是,并不是每一个人都知道如何打比方,以及如何才能准确地打比方。这两天和朋友聊天以及我看电视的经验表明这并不是一个简单的问题。因此想对这个问题说两点。

    1、打比方的第一个关键是要抓住问题的核心。换句话说,原问题和所打的比方必须具有共同的关键问题。很多比方,看似精妙,实际上是错误的。比如说,关于经济发展中的泡沫,曾经有非常著名的经济学家认为,它就像喝啤酒时的泡沫,有了泡沫喝起来才有味道。这不是一个好的比方。啤酒有泡沫才好喝,但经济发展有泡沫永远都是不好的。又是同一位经济学家,在别人问到他对经济发展的看法时说,经济发展就象骑自行车,太快了会摔跤,太慢了会倒。所以要不快不慢。这是个比较好的比方。因为经济增长太慢,社会问题就容易累积爆发出来。经济增长太快,就容易产生投资过热和通货膨胀等问题。

    打比方的第二个关键是必须用简单的东西来比喻复杂的问题,而不是用复杂的东西来比喻简单的问题。

    2、一种说明文的说明方法

    打比方是通过比喻的修辞方法来说明事物特征的一种方法。

    打比方的作用:使文章更具体、生动、形象。

    0

    2

    6

    tina

    2009-09-11

    举例子是举出代表性的能说明问题的例子来验证;

    列数字是用数字或者数据来更具有说服性,这个国家统计局最常用;

    作比较通常老师会用反面形象当做教材来比较正面形象;

    打比方也就是比喻,比如;

    0

    3

    6

    匿名用户

    2009-09-13

    举例子。举出实际事例来说明事物,使所要说明的事物具体化,以便读者理解,这种说明方法叫举例法。如:

    0

    3

    5

    翰林学士

    2009-09-13

    举例子:什么事水果啊?比如苹果,香蕉,西瓜等都是水果。列数字:我国约有13亿人。打比方:太阳像一个大火球。做比较:中国与其他国比,还是我们中国的人数多。

    0

    2

    4

    广告

    前往了解治疗方法

    推荐内容

    正在加载...

    © 2018 Sogou Inc.

    免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

    http://www.pinlue.com/style/images/nopic.gif

    更多相关内容
  • 引用大佬的博客: Java:强引用,软引用,弱引用和虚引用 建议直接看大佬的博客,我这里只做总结。 总结 强引用 相当于 Object obj=new Object()这种引用就是强引用,即使OOM也不会被垃圾回收器进行回收 软引用 如果...

    引用大佬的博客: Java:强引用,软引用,弱引用和虚引用

    建议直接看大佬的博客,我这里只做总结。

    总结

    强引用 相当于 Object obj=new Object()这种引用就是强引用,即使OOM也不会被垃圾回收器进行回收
    软引用 如果将要发生了OOM(内存不够用了)则会将对象自动回收
    弱引用 只要发生了gc()就会进行回收虚引用的对象
    虚引用 主要用来跟踪对象被垃圾回收的活动。虚引用必须和引用队列关联使用。

    案例:

    import java.lang.ref.*;
    
    public class WeakReferenceDemo {
    
        public static void main(String[] args) {
            softReferenceTest();// 软引用
            weakReferenceTest();// 弱引用
        }
    
        /**
         * 软引用测试案例
         * 会发现gc后软引用还能获取"hello world!!!",只有将要OOM的gc才会回收对象那么返回null
         */
        private static void softReferenceTest() {
            String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
            SoftReference<String> stringSoftReference = new SoftReference<>(helloWorldString);
            System.out.println("打印一下软引用的字符串:" + stringSoftReference.get());//没有进行gc前软引用能得到对象
            /**
             * 置 null 的作用
             * 去除helloWorldString强引用字符串"hello world!!!",
             * 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
             */
            helloWorldString = null;
            System.gc();//进行垃圾回收
            stringSoftReference.get();
            System.out.println("软引用的字符串被垃圾回收了,得到的字符串是:" + stringSoftReference.get());
        }
    
        /**
         * 弱引用测试案例
         * 会发现gc后,弱引用不能获取"hello world!!!"
         */
        private static void weakReferenceTest() {
            String helloWorldString = new String("hello world!!!"); // 在堆中根据常量字符串创建一个新的字符串对象
            WeakReference<String> stringWeakReference = new WeakReference<>(helloWorldString);// 创建一个弱引用,将弱引用指向堆中的那个字符串
    
            /**
             * 置 null 的作用
             * 去除helloWorldString强引用字符串"hello world!!!",
             * 因为对象一旦被强引用指向,即使内存不够,宁愿报错也不会被回收改对象,相当于"hello world!!!"原先由两个引用指向这个对象
             */
            helloWorldString = null;
            System.out.println("打印一下弱引用的字符串:" + stringWeakReference.get());//没有进行gc前软引用能得到对象
            System.gc();//进行垃圾回收
            stringWeakReference.get();
            System.out.println("弱引用的字符串被垃圾回收了,得到的字符串是:" + stringWeakReference.get());
        }
    }
    
    

    再度总结

    之所以要分成这四种引用,就是在gc的时候被引用的对象是否会被回收内存所分成的情况,以及考虑发生OOM的情况进行gc


    强引用: 不用举例子,平时new引用的对象就是强引用
    软引用: 可以通过SoftReference<Obj> sr = new SoftReference<Obj>(obj);进行引用,
    弱引用: 通过WeakReference<String> sr = new WeakReference<String>(new String("hello"));这个例子使用new创建对象为了避免对象在常量池中。
    虚引用: 主要用来跟踪对象被垃圾回收的活动(GCRoot中的引用链应该就是用这个做的,如果一个对象没有被引用GCRoot引用到,则说明这是一个内存垃圾,需要进行垃圾回收)


    虚引用的使用例子:

    ReferenceQueue<String> queue = new ReferenceQueue<String>();
    PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
    
    
    展开全文
  • 举例子说明Python引用和对象

    千次阅读 2019-07-10 20:32:44
    从最开始的变量开始思考:...第一个例子:  a = 1  这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1;这边形象比喻一下:这个过程就相当于“放风筝”,变量a就是你...

    从最开始的变量开始思考:

       在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可 (这个和C语言等静态类型语言不同,和python为动态类型有关)。

    举第一个例子:

        a = 1

       这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1;这边形象比喻一下:这个过程就相当于“放风筝”,变量a就是你手里面的“线”,python就跟那根“线”一样,通过引用来接触和拴住天空中的风筝——对象。

       你可以通过python的内置函数 id() 来查看对象的身份(identity),这个所谓的身份其实就是 对象 的内存地址:

        注:

         python一切皆对象的理念,所以函数也是一个对象,因此可以使用 id() 函数的__doc__方法来查看这个函数的具体描述。

    先举个例子:

     

    第一个语句中, 2是储存在内存中的一个整数对象,通过赋值 引用a 指向了 对象 1;

    第二个语句中,内存中建立了一个字符串对象‘banana’,通过赋值 将 引用a 指向了 ‘banana’,同时,对象1不在有引用指向它,它会被python的内存处理机制给当我垃圾回收,释放内存。

    再举一个例子:

     

    第一个语句中, 2是储存在内存中的一个整数对象,通过赋值 引用a 指向了 对象 1;

    第二个语句中,内存中建立了一个字符串对象‘banana’,通过赋值 将 引用a 指向了 ‘banana’,同时,对象1不在有引用指向它,它会被python的内存处理机制给当我垃圾回收,释放内存。

     

    再来一个例子:

    通过函数查看 变量a 和 变量b的引用情况:

     

    在这里可以看到  这俩个引用 指向了同一个 对象,这是为什么呢? 这个跟python的内存机制有关系,因为对于语言来说,频繁的进行对象的销毁和建立,特别浪费性能。所以在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。

    然后再看看这个例子:

     1.  a = 4

        2.  b = a(这里就是让引用b指向引用a指向的那个对象)

        3.  a = a + 2

       通过函数查看引用情况:

        当执行到第2步的时候,查看一下 a 和 b 的引用:

     

    可以看到 a 和 b 都指向了 整数对象 4

        接下来指向第3步:

     

    可以看到 a 的引用改变了,但是 b 的引用未发生改变;a,b指向不同的对象; 第3句对 a 进行了重新赋值,让它指向了新的 对象6;即使是多个引用指向同一个对象,如果一个引用值发生变化,那么实际上是让这个引用指向一个新的引用,并不影响其他的引用的指向。从效果上看,就是各个引用各自独立,互不影响。

    还有一个必须要看的例子:

     

    所以,每次列表实际上都是添加同一个对象。

     

    copy.copy() 浅拷贝。只拷贝父对象,不会拷贝对象的内部的子对象。

    那么,copy.copy()和copy.deepcopy()有什么区别呢?

     

    copy.deepcopy() 深拷贝 拷贝对象及其子对象。

    最后一个例子:

    (这个栗子会涉及到 python中的 可变数据类型 和 不可变数据类型):

       开始这个栗子之前,请记得注意到 第四个栗子的不同之处。

         1.   L1 = [1, 2, 3]

         2.   L2 = L1

         3.   L1[0] = 10

       通过函数查看引用情况:

       当执行第1步 和 第二步 的时候,查看一下 L1 和 L2 的引用情况:

     

    此时 L1 和 L2 的引用相同,都是指向 [1,2,3]这个列表对象。

    接下来,继续执行第3步:

     

    同样的跟第四个栗子那样,修改了其中一个对象的值,但是可以发现 结果 并不与 第四个栗子那样, 在本次实验中,L1 和 L2 的引用没有发生任何变化,但是 列表对象[1,2,3] 的值 变成了 [10,2,3](列表对象改变了)

    在该情况下,我们不再对L1这一引用赋值,而是对L1所指向的表的元素赋值。结果是,L2也同时发生变化。

    原因何在呢?因为L1,L2的指向没有发生变化,依然指向那个表。表实际上是包含了多个引用的对象(每个引用是一个元素,比如L1[0],L1[1]..., 每个引用指向一个对象,比如1,2,3), 。而L1[0] = 10这一赋值操作,并不是改变L1的指向,而是对L1[0], 也就是表对象的一部份(一个元素),进行操作,所以所有指向该对象的引用都受到影响。

    (与之形成对比的是,我们之前的赋值操作都没有对对象自身发生作用,只是改变引用指向。)

    列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。

    而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。

    我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.

    展开全文
  • Java值传递和引用传递详细说明

    千次阅读 多人点赞 2020-07-14 15:53:17
    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用...其实,对于值传递和引用传递的语法运用,百度一下,就能出来可观的解释和例子数目,或许你看一下例子好像就懂,但是当你参加面

    本文旨在用最通俗的语言讲述最枯燥的基本知识

    学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java只有值传递,有的博客说两者皆有;这让人有点摸不着头脑,下面我们就这个话题做一些探讨,对书籍、对论坛博客的说法,做一次考证,以得出信得过的答案。

    其实,对于值传递和引用传递的语法和运用,百度一下,就能出来可观的解释和例子数目,或许你看一下例子好像就懂,但是当你参加面试,做一道这个知识点的笔试题时感觉自己会,胸有成熟的写了答案,却发现是错的,或者是你根本不会做。

    是什么原因?

    那是因为你对知识点没有了解透彻,只知道其皮毛。要熟读一个语法很简单,要理解一行代码也不难,但是能把学过的知识融会贯通,串联起来理解,那就是非常难了,在此,关于值传递和引用传递,小编会从以前学过的基础知识开始,从内存模型开始,一步步的引出值传递和引用传递的本质原理,故篇幅较长,知识点较多,望读者多有包涵。

    1. 形参与实参

    我们先来重温一组语法:

    1. 形参:方法被调用时需要传递进来的参数,如:func(int a)中的a,它只有在func被调用期间a才有意义,也就是会被分配内存空间,在方法func执行完成后,a就会被销毁释放空间,也就是不存在了

    2. 实参:方法被调用时是传入的实际值,它在方法被调用前就已经被初始化并且在方法被调用时传入。

    举个栗子:

    1public static void func(int a){
    2 a=20;
    3 System.out.println(a);
    4}
    5public static void main(String[] args) {
    6 int a=10;//变量
    7 func(a);
    8}
    

    例子中
    int a=10;中的a在被调用之前就已经创建并初始化,在调用func方法时,他被当做参数传入,所以这个a是实参。
    而func(int a)中的a只有在func被调用时它的生命周期才开始,而在func调用结束之后,它也随之被JVM释放掉,,所以这个a是形参。

    2. Java的数据类型

    所谓数据类型,是编程语言中对内存的一种抽象表达方式,我们知道程序是由代码文件和静态资源组成,在程序被运行前,这些代码存在在硬盘里,程序开始运行,这些代码会被转成计算机能识别的内容放到内存中被执行。
    因此

    数据类型实质上是用来定义编程语言中相同类型的数据的存储形式,也就是决定了如何将代表这些值的位存储到计算机的内存中。

    所以,数据在内存中的存储,是根据数据类型来划定存储形式和存储位置的。
    那么
    Java的数据类型有哪些?

    1. 基本类型:编程语言中内置的最小粒度的数据类型。它包括四大类八种类型:

    4种整数类型:byte、short、int、long
    2种浮点数类型:float、double
    1种字符类型:char
    1种布尔类型:boolean

    1. 引用类型:引用也叫句柄,引用类型,是编程语言中定义的在句柄中存放着实际内容所在地址的地址值的一种数据形式。它主要包括:


    接口
    数组

    有了数据类型,JVM对程序数据的管理就规范化了,不同的数据类型,它的存储形式和位置是不一样的,要想知道JVM是怎么存储各种类型的数据,就得先了解JVM的内存划分以及每部分的职能。

    3.JVM内存的划分及职能

    Java语言本身是不能操作内存的,它的一切都是交给JVM来管理和控制的,因此Java内存区域的划分也就是JVM的区域划分,在说JVM的内存划分之前,我们先来看一下Java程序的执行过程,如下图:

    640?wx_fmt=png


    有图可以看出:Java代码被编译器编译成字节码之后,JVM开辟一片内存空间(也叫运行时数据区),通过类加载器加到到运行时数据区来存储程序执行期间需要用到的数据和相关信息,在这个数据区中,它由以下几部分组成:

     

    1. 虚拟机栈

    2. 堆

    3. 程序计数器

    4. 方法区

    5. 本地方法栈

    我们接着来了解一下每部分的原理以及具体用来存储程序执行过程中的哪些数据。


    1. 虚拟机栈

    虚拟机栈是Java方法执行的内存模型,栈中存放着栈帧,每个栈帧分别对应一个被调用的方法,方法的调用过程对应栈帧在虚拟机中入栈到出栈的过程。

    栈是线程私有的,也就是线程之间的栈是隔离的;当程序中某个线程开始执行一个方法时就会相应的创建一个栈帧并且入栈(位于栈顶),在方法结束后,栈帧出栈。

    下图表示了一个Java栈的模型以及栈帧的组成:

    640?wx_fmt=png


    栈帧:是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。

     

    每个栈帧中包括:

    1. 局部变量表:用来存储方法中的局部变量(非静态变量、函数形参)。当变量为基本数据类型时,直接存储值,当变量为引用类型时,存储的是指向具体对象的引用。

    2. 操作数栈:Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",其中所指的栈就是指操作数栈。

    3. 指向运行时常量池的引用:存储程序执行时可能用到常量的引用。

    4. 方法返回地址:存储方法执行完成后的返回地址。


    2. 堆:

    堆是用来存储对象本身和数组的,在JVM中只有一个堆,因此,堆是被所有线程共享的。


    3. 方法区:

    方法区是一块所有线程共享的内存逻辑区域,在JVM中只有一个方法区,用来存储一些线程可共享的内容,它是线程安全的,多个线程同时访问方法区中同一个内容时,只能有一个线程装载该数据,其它线程只能等待。

    方法区可存储的内容有:类的全路径名、类的直接超类的权全限定名、类的访问修饰符、类的类型(类或接口)、类的直接接口全限定名的有序列表、常量池(字段,方法信息,静态变量,类型引用(class))等。


    4. 本地方法栈:

    本地方法栈的功能和虚拟机栈是基本一致的,并且也是线程私有的,它们的区别在于虚拟机栈是为执行Java方法服务的,而本地方法栈是为执行本地方法服务的。

    有人会疑惑:什么是本地方法?为什么Java还要调用本地方法?


    5. 程序计数器:

    线程私有的。
    记录着当前线程所执行的字节码的行号指示器,在程序运行过程中,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、异常处理、线程恢复等基础功能都需要依赖计数器完成。


    4. 数据如何在内存中存储?

    从上面程序运行图我们可以看到,JVM在程序运行时的内存分配有三个地方:

    • 静态方法区

    • 常量区

    相应地,每个存储区域都有自己的内存分配策略:

    • 堆式:

    • 栈式

    • 静态

    我们已经知道:Java中的数据类型有基本数据类型和引用数据类型,那么这些数据的存储都使用哪一种策略呢?
    这里要分以下的情况进行探究:

    1. 基本数据类型的存储:

    • A. 基本数据类型的局部变量

    • B. 基本数据类型的成员变量

    • C. 基本数据类型的静态变量

    2. 引用数据类型的存储


    1. 基本数据类型的存储


    我们分别来研究一下:

    A.基本数据类型的局部变量

    1. 定义基本数据类型的局部变量以及数据都是直接存储在内存中的栈上,也就是前面说到的“虚拟机栈”,数据本身的值就是存储在栈空间里面。

      640?wx_fmt=png


      如上图,在方法内定义的变量直接存储在栈中,如

    1int age=50;
    2int weight=50;
    3int grade=6;
    

    当我们写“int age=50;”,其实是分为两步的:

    1int age;//定义变量
    2age=50;//赋值
    

    首先JVM创建一个名为age的变量,存于局部变量表中,然后去栈中查找是否存在有字面量值为50的内容,如果有就直接把age指向这个地址,如果没有,JVM会在栈中开辟一块空间来存储“50”这个内容,并且把age指向这个地址。因此我们可以知道:
    我们声明并初始化基本数据类型的局部变量时,变量名以及字面量值都是存储在栈中,而且是真实的内容。

    我们再来看“int weight=50;”,按照刚才的思路:字面量为50的内容在栈中已经存在,因此weight是直接指向这个地址的。由此可见:栈中的数据在当前线程下是共享的

    那么如果再执行下面的代码呢?

    1weight=40;
    

    当代码中重新给weight变量进行赋值时,JVM会去栈中寻找字面量为40的内容,发现没有,就会开辟一块内存空间存储40这个内容,并且把weight指向这个地址。由此可知:

    基本数据类型的数据本身是不会改变的,当局部变量重新赋值时,并不是在内存中改变字面量内容,而是重新在栈中寻找已存在的相同的数据,若栈中不存在,则重新开辟内存存新数据,并且把要重新赋值的局部变量的引用指向新数据所在地址。


    B. 基本数据类型的成员变量

    成员变量:顾名思义,就是在类体中定义的变量。
    看下图:

    640?wx_fmt=png

     

    我们看per的地址指向的是堆内存中的一块区域,我们来还原一下代码:

     1public class Person{
     2  private int age;
     3  private String name;
     4  private int grade;
     5//篇幅较长,省略setter getter方法
     6  static void run(){
     7     System.out.println("run...."); 
     8   };
     9}
    10
    11//调用
    12Person per=new Person();
    

    同样是局部变量的age、name、grade却被存储到了堆中为per对象开辟的一块空间中。因此可知:基本数据类型的成员变量名和值都存储于堆中,其生命周期和对象的是一致的。


    C. 基本数据类型的静态变量

    前面提到方法区用来存储一些共享数据,因此基本数据类型的静态变量名以及值存储于方法区的运行时常量池中,静态变量随类加载而加载,随类消失而消失


    2. 引用数据类型的存储:

    上面提到:堆是用来存储对象本身和数组,而引用(句柄)存放的是实际内容的地址值,因此通过上面的程序运行图,也可以看出,当我们定义一个对象时

    1Person per=new Person();
    

    实际上,它也是有两个过程:

    1Person per;//定义变量
    2per=new Person();//赋值
    

    在执行Person per;时,JVM先在虚拟机栈中的变量表中开辟一块内存存放per变量,在执行per=new Person()时,JVM会创建一个Person类的实例对象并在堆中开辟一块内存存储这个实例,同时把实例的地址值赋值给per变量。因此可见:
    对于引用数据类型的对象/数组,变量名存在栈中,变量值存储的是对象的地址,并不是对象的实际内容。

    6. 值传递和引用传递

    前面已经介绍过形参和实参,也介绍了数据类型以及数据在内存中的存储形式,接下来,就是文章的主题:值传递和引用的传递。

    值传递:
    在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。

    来看个例子:

     1public static void valueCrossTest(int age,float weight){
     2    System.out.println("传入的age:"+age);
     3    System.out.println("传入的weight:"+weight);
     4    age=33;
     5    weight=89.5f;
     6    System.out.println("方法内重新赋值后的age:"+age);
     7    System.out.println("方法内重新赋值后的weight:"+weight);
     8    }
     9
    10//测试
    11public static void main(String[] args) {
    12        int a=25;
    13        float w=77.5f;
    14        valueCrossTest(a,w);
    15        System.out.println("方法执行后的age:"+a);
    16        System.out.println("方法执行后的weight:"+w);
    17}
    

    输出结果:

    1传入的age:25
    2传入的weight:77.5
    3
    4方法内重新赋值后的age:33
    5方法内重新赋值后的weight:89.5
    6
    7方法执行后的age:25
    8方法执行后的weight:77.5
    

    从上面的打印结果可以看到:
    a和w作为实参传入valueCrossTest之后,无论在方法内做了什么操作,最终a和w都没变化。

    这是什么造型呢?!!

    下面我们根据上面学到的知识点,进行详细的分析:

    首先程序运行时,调用mian()方法,此时JVM为main()方法往虚拟机栈中压入一个栈帧,即为当前栈帧,用来存放main()中的局部变量表(包括参数)、操作栈、方法出口等信息,如a和w都是mian()方法中的局部变量,因此可以断定,a和w是躺着mian方法所在的栈帧中
    如图:

    640?wx_fmt=jpeg


    而当执行到valueCrossTest()方法时,JVM也为其往虚拟机栈中压入一个栈,即为当前栈帧,用来存放valueCrossTest()中的局部变量等信息,因此age和weight是躺着valueCrossTest方法所在的栈帧中,而他们的值是从a和w的值copy了一份副本而得,如图:

    640?wx_fmt=png

    因而可以a和age、w和weight对应的内容是不一致的,所以当在方法内重新赋值时,实际流程如图:

    640?wx_fmt=jpeg

    也就是说,age和weight的改动,只是改变了当前栈帧(valueCrossTest方法所在栈帧)里的内容,当方法执行结束之后,这些局部变量都会被销毁,mian方法所在栈帧重新回到栈顶,成为当前栈帧,再次输出a和w时,依然是初始化时的内容。
    因此:
    值传递传递的是真实内容的一个副本,对副本的操作不影响原内容,也就是形参怎么变化,不会影响实参对应的内容。

     

    引用传递:
    ”引用”也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向通愉快内存地址,对形参的操作会影响的真实内容。

    举个栗子:
    先定义一个对象:

     1public class Person {
     2        private String name;
     3        private int age;
     4
     5        public String getName() {
     6            return name;
     7        }
     8        public void setName(String name) {
     9            this.name = name;
    10        }
    11        public int getAge() {
    12            return age;
    13        }
    14        public void setAge(int age) {
    15            this.age = age;
    16        }
    17}
    

    我们写个函数测试一下:

     1public static void PersonCrossTest(Person person){
     2        System.out.println("传入的person的name:"+person.getName());
     3        person.setName("我是张小龙");
     4        System.out.println("方法内重新赋值后的name:"+person.getName());
     5    }
     6//测试
     7public static void main(String[] args) {
     8        Person p=new Person();
     9        p.setName("我是马化腾");
    10        p.setAge(45);
    11        PersonCrossTest(p);
    12        System.out.println("方法执行后的name:"+p.getName());
    13}
    

    输出结果:

    1传入的person的name:我是马化腾
    2方法内重新赋值后的name:我是张小龙
    3方法执行后的name:我是张小龙
    

    可以看出,person经过personCrossTest()方法的执行之后,内容发生了改变,这印证了上面所说的“引用传递”,对形参的操作,改变了实际对象的内容。

    那么,到这里就结题了吗?
    不是的,没那么简单,
    能看得到想要的效果
    是因为刚好选对了例子而已!!!

    下面我们对上面的例子稍作修改,加上一行代码,

    1public static void PersonCrossTest(Person person){
    2        System.out.println("传入的person的name:"+person.getName());
    3        person=new Person();//加多此行代码
    4        person.setName("我是张小龙");
    5        System.out.println("方法内重新赋值后的name:"+person.getName());
    6    }
    

    输出结果:

    1传入的person的name:我是马化腾
    2方法内重新赋值后的name:我是张小龙
    3方法执行后的name:我是马化腾
    

    `
    为什么这次的输出和上次的不一样了呢?
    看出什么问题了吗?

    按照上面讲到JVM内存模型可以知道,对象和数组是存储在Java堆区的,而且堆区是共享的,因此程序执行到main()方法中的下列代码时

    1Person p=new Person();
    2        p.setName("我是马化腾");
    3        p.setAge(45);
    4        PersonCrossTest(p);
    

    JVM会在堆内开辟一块内存,用来存储p对象的所有内容,同时在main()方法所在线程的栈区中创建一个引用p存储堆区中p对象的真实地址,如图:

    640?wx_fmt=png


    当执行到PersonCrossTest()方法时,因为方法内有这么一行代码:

    1person=new Person();
    

    JVM需要在堆内另外开辟一块内存来存储new Person(),假如地址为“xo3333”,那此时形参person指向了这个地址,假如真的是引用传递,那么由上面讲到:引用传递中形参实参指向同一个对象,形参的操作会改变实参对象的改变

    可以推出:实参也应该指向了新创建的person对象的地址,所以在执行PersonCrossTest()结束之后,最终输出的应该是后面创建的对象内容。

    然而实际上,最终的输出结果却跟我们推测的不一样,最终输出的仍然是一开始创建的对象的内容。

    由此可见:引用传递,在Java中并不存在。

    但是有人会疑问:为什么第一个例子中,在方法内修改了形参的内容,会导致原始对象的内容发生改变呢?

    这是因为:无论是基本类型和是引用类型,在实参传入形参时,都是值传递,也就是说传递的都是一个副本,而不是内容本身。

    640?wx_fmt=png

     

    有图可以看出,方法内的形参person和实参p并无实质关联,它只是由p处copy了一份指向对象的地址,此时:

    p和person都是指向同一个对象

    因此在第一个例子中,对形参p的操作,会影响到实参对应的对象内容。而在第二个例子中,当执行到new Person()之后,JVM在堆内开辟一块空间存储新对象,并且把person改成指向新对象的地址,此时:

    p依旧是指向旧的对象,person指向新对象的地址。

    所以此时对person的操作,实际上是对新对象的操作,于实参p中对应的对象毫无关系

    结语

    因此可见:在Java中所有的参数传递,不管基本类型还是引用类型,都是值传递,或者说是副本传递。
    只是在传递过程中:

    如果是对基本数据类型的数据进行操作,由于原始内容和副本都是存储实际值,并且是在不同的栈区,因此形参的操作,不影响原始内容。

    如果是对引用类型的数据进行操作,分两种情况,一种是形参和实参保持指向同一个对象地址,则形参的操作,会影响实参指向的对象的内容。一种是形参被改动指向新的对象地址(如重新赋值引用),则形参的操作,不会影响实参指向的对象的内容。

    原文转至:https://blog.csdn.net/bntx2jsqfehy7/article/details/83508006

    展开全文
  • 主要介绍了理解C#中参数的值和引用以及传递结构引用区别,文中了两段代码例子来简单说明,需要的朋友可以参考下
  • Java 如何有效地避免OOM:善于利用软引用和引用。  想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引用来有效地解决程序...
  • 说明方法例句

    2020-12-21 14:01:17
    常见的说明方法有举例子、作引用、分类别、列数字、作比较、列图表、下定义、作诠释、打比方、摹状貌、作假设这10种。小学常见的有:举例子、列数字、打比方、分类别、作比较。中学常见的有:举例子、列数字、打比方...
  • 刚刚接触Java时应该听说过一...对于对象的引用,心里大概知道,却不知怎么表达。还有一个问题就是Java是值传递还是引用传递,在C语言中这个问题看到的比较多,在Java中似乎没怎么探讨过。下面围绕上面两个问题来分析!
  • 一个数据库实际的例子: create or replace trigger tr_tp_departs before insert or update on tp_departs 在tp_departs表上 for each row //每行 begin  :new.PINYIN := f_pinyin(:new.JGMC); //建一个f...
  • 十种说明方法造句

    千次阅读 2020-12-21 14:01:16
    怎么用十种说明方法造句,在线等,急举例子: 他是个热心肠的人,有一次下雨天他把伞借给一个老奶奶,自己却淋着雨。列数字: 赵州桥非常雄伟,全长50。82米,两端宽9。6米,中部略窄,宽9米。打比方: 弯弯的月亮像...
  • 常用说明方法的作用举例子定义:举出实际事例来说明事物,使所要说明的事物具体化,以便读者理解,这种说明方法叫举例子。运用举事例的说明方法说明事物或事理,一要注意例子的代表性,二要注意例子的适量性。(好处...
  • 说明文方法的答题格式

    千次阅读 2021-01-30 18:18:56
    说明文方法的答题格式各位知道说明文方法的答题格式是这样的吗?下面小编给大家介绍,一起看看吧。说明文方法的答题格式一、分类1、从说明对象的角度:事物性说明文、事理性说明文。2、从说明文语言特征:平实的说明...
  • 例子说明: 复制代码 代码如下: <?php   $color = ‘YellowGreen’;   function &getRef() {  global $color;  return $color; }   function getCopy() {  global $color;  return $color; }
  • 说明文方法答题格式

    千次阅读 2021-02-11 21:30:16
    说明文方法答题格式说明文是一种以说明为主要表达方式的文章体裁。它通过对实体事物科学地解说,对客观事物做出说明或对抽象事理的阐释,使人们对事物的形态、构造、性质、种类、成因、功能、关系或对事理的概念、...
  • //错误 4.2 『i++ 不能作为左值,而++i 可以』 // 前缀形式: int& int::operator++() //这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用 {//函数本身无参,意味着是在自身空间内增加1的 *this ...
  • 指针和引用作为函数参数的区别

    千次阅读 2018-12-02 10:37:50
    这个问题是在写平衡树的时候遇见的,到网上看了很多,也没明白,自己尝试了一些例子来对比,终于明白了。 一言以蔽之:如果想改变一般类型的参数的值,可以使用变量的指针做参数;如果想改变指针变量指向的地址...
  • 举例子:晕能预示天气。比如,在新疆地区,出现晕。映入眼帘的是一个晶莹的球体,上面蓝色白色的纹痕相互交错,周围裹着一层薄薄的水蓝色“纱衣”。多少(打比方) 地球,这位人类的母亲,这个生命的摇篮,是那样的...
  • 学过java基础的人都知道,在java中参数的传递过程中有值传递应用传递,那么这两个到底有什么区别呢,下面我通过例子为大家详细的介绍下。 我们都知道Java中有八种数据类型,基础数据类型分别是:byte,short,int...
  • 用一个例子说明什么是多态

    千次阅读 2012-11-13 16:20:01
    OOP面向对象的三个特性:封装、继承多态。前面两个特性好理解,多态则常常搞得很多人...引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对
  • 我们来例子说明一下LHSRHS。 var a = 1; 我们把这个表达式根据等号拆成两个部分,var a = 1。这个里面var a进行的LHS查找,编译器遇到var a时,会询问作用域是否存在一个名为a的变量,如果有则忽略,...
  • JVM的符号引用和直接引用是什么

    千次阅读 多人点赞 2019-07-08 22:58:49
    符号引用就是一个类中(当然不仅是类,还包括类的其他部分,比如方法,字段等),引入了其他的类,可是JVM并不知道引入的其他类在哪里,所以就用唯一符号来代替,等到类加载器去解析的时候,就把符号引用找到那个...
  • C++对象指针的引用

    2012-04-26 23:34:36
    例子说明对象引用作函数参数的格式。 #include class M { public: M() { x=y=0; } M(int i, int j) { x=i; y=j; } void copy(M &m); void setxy(int i, int j) { x=i; y=j; } void print() {cout,...
  • 一、前言 Objective-C 使用引用计数作为 iPhone 应用的内存...虽然 Objective-C 通过引入弱引用技术,让开发者可以尽可能地规避这个问题,但在引用层级过深,引用路径不那么直观的情况下,即使是经验丰富的工程师,也
  • JAVA参数传递方式 (按值传递与引用传递区别)

    万次阅读 多人点赞 2018-09-30 22:58:30
    首先要明确的是JAVA中没有引用传递, 全部是按值调用 令大家所费解的 当对象引用作为参数时 函数为什么能修改真实的对象呢?这不是引用传递的特征吗? 尤其先学习C++再学习JAVA的同学(比如说我自己)会这样认为, 用...
  • 程序的依赖和引用是什么?

    千次阅读 多人点赞 2019-09-30 22:08:02
    例子,我现在需要做一道菜,我想调用厨师这个类(class)帮我完成工作,我对厨师之前形成依赖。厨师怎么做呢?在厨师这个类里面有个叫“降龙十八炒”的方法(function),于是我可以调用厨师这个类当中的这个方法...
  • C++11的右值引用、移动语义(std::move)完美转发(std::forward)详解1、源码准备2、C++11右值引用概念2.1、左值右值2.2、右值引用3、C++11的移动语义(std::move)完美转发(std::forward)3.1、移动语义...
  • JAVA的符号引用和直接引用

    千次阅读 多人点赞 2018-08-14 22:12:49
    以变量例子: 符号引用要转换成直接引用才有效,这也说明直接引用的效率要比符号引用高。那为什么要用符号引用呢?这是因为类加载之前,javac会将源代码编译成.class文件,这个时候javac是不知道被编译的类中...
  • 重载运算符时的参数返回类型要用引用说明

    千次阅读 多人点赞 2017-07-12 16:17:04
    一·我们个必须要用重载运算符重载运算符时必须要使用引用例子 #include #pragma pack(8) using namespace std; class Myclass { private: char* str; public: Myclass(char* str1 = "default string") { ...
  • 说明方法,是写说明文时用简明扼要的语言把事物的实际情况恰如其分地表述...下面是详细解释举例:1、举例子举出实际事例来说明事物,使所要说明的事物具体化,以便读者理解,这种说明方法叫举例子.好处:使文章表达的...
  • 考虑到查找替换中使用的正则表达式反引用的时候未必支持复杂的条件表达式(至少没查到类似的手册说明), 那么这种替换规则,似乎简化的操作方法就是分开来: 只有一位小数的查找匹配项: \d { 1,2 } \. \d { 1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,489
精华内容 54,995
关键字:

引用说明和举例子的区别