你说的是什么意思?
java中每一个变量,都是对对象的一个引用。java中,引用无所不在,没有引用就没有java.不过,这个引用的概念和C++的完全不同(但是和ObjectPascal(Delphi的语言)是一致的).

解决方案 »

  1.   

    指针可以到处指,而java的变量只能指向合法的对象,跟类型也严格相关。
    所以,c/c++的指针在很多情况下可能指向毫无意义的内存单元,而java的引用从语法上避免了这一点,总是指向有意义的数据,也就自然的避免了可能的bug.
      

  2.   

    我的意思是在C++的函数中,如果它的一个参数我在函数外部声明,但并末给它一个初始化值,然后我把这个变量经C++引用的形式传入这个函数,函数经处理经这个传进来的变量赋了一个值,但函数本身并末返回任何的的东西,出了这个函数的作用域后,这个在外部定义的变量就有了一个值,在java中如何作到这点。我是个菜鸟,请详细指点。
      

  3.   

    贴偶翻译的一个文章,讲的是C#里值类型和引用类型的区别,不知和java的概念是不是一样。
    C#概念:值类型vs引用类型    
       
     
    本帖版权归原作者,其它媒体或网站转载请与e龙西祠胡同[http://www.xici.net]或原作者联系,并注明出处。  
     作者: Ripper 发表日期: 2001-05-31 15:11:59 返回《.NET》 快速返回
    C# Concepts: Value vs Reference Types
    Joseph AlbaharirIPPER又来翻译了 C#概念:值类型vs引用类型
    Introduction
    One area likely to cause confusion for those coming from a Java or VB6 background is the distinction between value types and reference types in C#. In particular, C# provides two types – class and struct, which are almost the same except that one is a reference type while the other is a value type. This article explores their essential differences, and the practical implications when programming in C#.class 和 struct非常相似This article assumes you have a basic knowledge of C#, and are able to define classes and properties.当然你要了解一点C#,知道怎么声明class和property。
    Firstly, What Are Structs?
    Put simply, structs are lightweight classes. Imagine classes cut-down so that they don’t support inheritance or destructors, and we have the low-overhead version: the struct. They are defined in the same way as classes (except with the struct keyword), and apart from a few minor limitations, can have the same rich members, including fields, methods, properties and operators. Here is a simple struct declaration:struct就是轻型的class,和class不同的地方是它没有继承和析构函数destructor。定义struct和定义class相似,一个struct可以有成员变量、方法、属性、运算符、fields(这是什么?rIPPER也不晓得)下面就是一个例子:struct Point
    {
      private int x, y;        // private fields  (呵呵,原来就是这个啊 ;)  public Point (int x, int y) {  // constructor
         this.x = x;
         this.y = y;
      }  public int X {          // property
         get {return x;}
         set {x = value;}
      }  public int Y {
         get {return y;}
         set {y = value;}
      }
    }  Value and Reference Types
    值类型和引用类型There is another difference between structs and classes, and this is also the most important to understand. Structs are value types, while classes are reference types, and they are dealt with in different ways. When a value-type object is created, C# allocates a single space in memory, and puts the contents of the object into it. Primitive types such as int, float, bool or char are also value types, and they are instantiated in the same way. When the runtime deals with a value type, it's dealing directly with its underlying data and this can be very efficient, particularly with primitive types.最重要的地方是,struct是值类型,而class是引用类型。当值类型被创建时,会分配一块内存区,并把对象的内容(content)copy到里面。C#本身包含的类型比如int、float、bool、char也是值类型的。With reference types, however, an object is created in memory, and then handled through a separate reference – rather like a pointer. Suppose Point is a struct, and Form is a class. If we create an object of each type:而引用类型是用一个引用指向内存当中的对象,看看下面的例子,p1就是内存中对象本身,而f1是指向内存中一个对象的引用。Point p1 = new Point();     // Point is a *struct*
    Form f1 = new Form();      // Form is a *class*
    in the first case, one space in memory will be allocated for p1, while in the second case two spaces will be allocated - one for a Form object and another for its reference (f1). It's clearer when we go about it the long way:下面的例子更清楚,f1是一个引用,new为它分配了一块内存Form f1;            // Allocate the reference
    f1 = new Form();        // Allocate the object
    If we copy the objects to new variables:如果我们copy对象Point p2 = p1;
    Form f2 = f1;
    p2, being a struct, becomes an independent copy of p1, with its own separate fields. But in the case of f2, all we’ve copied is a reference, with the result that both f1 and f2 point to the same object.第一行做的是值拷贝,p1和p2是独立的两变量,拥有独立的内存区域。而f2,它是一个引用,f2=f1做的是引用的copy,所以f2和f1都指向同一个对象。This is of particular interest when passing parameters to methods. In C#, parameters are by default passed by value, meaning a copy of them is given to the method. For value-type parameters, this means physically copying the object (in the same way p2 was copied), while for reference-types it means copying a pointer (in the same way f2 was copied). Here is an example:在传递方法参数时,值类型和引用类型的区别更加有意思。C#里参数在缺省情况下是传值的。对于值类型就像p2显示的情况。而引用类型就会象f2一样,传递一个引用作为参数。Point myPoint = new Point (0, 0);   // a new value-type variable
    Form myForm = new Form();       // a new reference-type variableTest (myPoint, myForm);        // Test is a method defined belowvoid Test (Point p, Form f) {
       p.X = 100;            // No effect on MyPoint since p is a copy
       f.Text = “Hello, World!”;    // This will change myForm’s caption since
                        // myForm and f point to the same object//f和myForm指向同一个对象,所以窗口的标题会改变
       f = null;            // No effect on myForm
    }
    Assigning null to f has no effect because f is a copy of a reference – and we’ve only erased the copy.给f赋null不会影响myForm,因为f只是一个引用的copy,我们只是删掉了引用的copy而已。We can change the way parameters are marshalled with the ref modifier. When passing by “reference”, the method interacts directly with the caller’s arguments. In the example below, you can think of the parameters p and f being replaced by myPoint and myForm:如果用ref 来指定传参数的方法,那么值类型的引用会被传到函数里去,见下面的myPoint。而对于引用类型,系统不会把引用的copy传递到函数,而是把引用本身传进去。请注意这里和传值参数的不同,当传值是,不论引用类型还是值类型都会被复制一份,再传到函数里。而引用传递则是为值类型创建一个引用传递给函数,对于引用类型会直接把这个引用传进函数。Point myPoint = new Point (0, 0);   // a new value-type variable
    Form myForm = new Form();       // a new reference-type variableTest (ref myPoint, ref myForm);    // pass myPoint and myForm by referencevoid Test (ref Point p, ref Form f) {
       p.X = 100;            // This will change myPoint’s position
       f.Text = “Hello, World!”;    // This will change MyForm’s caption
       f = null;            // This will nuke the myForm variable!
    }
    In this case, assigning null to f also makes myForm null, because this time we’re dealing with the original reference variable and not a copy of it.这次f=null就会让,myForm编成空了。因为f就是myForm本身而不是myForm的一个拷贝。
    Memory Allocation
    内存分配The Common Language Runtime allocates memory for objects in two places: on the stack and in the heap. The stack is an orderly first-in last-out memory structure, and is used for storing value-type objects. When a method is invoked, the CLR books the top of the stack, and then allocates memory on top of this for any value type objects (including local variables) that are created. When the method completes, the stack is 'popped' back to the book and all the value-type objects created - and their associated memory - are released.CLR会把对象分配到stack和heap中。stack是FIFO的内存结构,用于存储值类型对象。The heap, on the other hand, can be pictured as a disorderly jumble of objects, suitable for objects managed by reference. When a reference-type object is created, the CLR allocates a block of heap memory, creates the object, then gives us a reference to it. While the object itself will always be created on the heap, its reference may either exist on the heap or stack - depending on whether it’s part of another heap-object, or is a local variable such as in this example:heap则适合放由引用所维护的对象。创建引用类型的时候,CLR分配一块heap内存,创建对象,并让一个引用指向它。对象总是建立在heap中,而指向它的的引用则可能存在在heap中,也可能在stack中。这要看它到底是一个heap对象的一部分,还是一个象下面例子里的local变量:void CreateNewTextBox()
    {
       TextBox myTextBox = new TextBox();       // TextBox is a class
    }
    The actual reference variable (myTextBox) is created on the stack, but the object itself, as always, is on the heap:(抱歉图帖不出来,要看的话到:http://www.albahari.com/value%20vs%20reference%20types.html 去看)引用变量myTextBox在stack里,而对象本身在heap里。Memory Disposal
    Once CreateNewTextBox has finished running, its local stack-allocated variable, myTextBox, will disappear from scope and be deleted from memory. However, what will happen to the now orphaned object on the heap to which it was pointing? From a memory perspective, we can ignore it, because the garbage collection system will in due course identify that the object has no valid referee (one whose chain of reference originates back to a stack-allocated object) and automatically delete it. [1] C++ programmers may be a bit uncomfortable with this and may want to delete the object anyway – just to be sure! – but in fact there is no way to delete it explicitly. We have to rely on the Common Language Runtime for memory disposal – and indeed, the whole .NET framework does just that!当myTextBox出了作用域scope 后会从内存中删掉。那么它原来所指向的对象哪?我们可以不去考虑它的存在,因为GC(垃圾收集)可以去掉它。C++程序员可能觉得不爽,看到没有引用的对象就想删掉它。不过并没有显式的办法可以删除它。我们只有让CLR来管理它。However there is a caveat on automatic destruction. Objects that own resources other than memory (in particular “handles”, such as Windows handles, file handles and SQL handles) need to be told explicitly to release those resources when the object is no longer required. This includes all Windows controls, since they all own Windows handles! You might ask, why not put the code to release those resources in the object’s destructor? There are two reasons for this:然而自动析构还有问题。除了内存,对象可能还拥有其他的一些资源,比如Windows handles、,file handles 和 SQL handles。对象必须显式地释放这些资源。所有Windows controls都必须这么做,因为它们拥有windows handles!你可能会想,为什么不把这些放在析构函数里完成哪?有两原因:1.The automatic garbage collector, which is responsible for initiating the destructor (by identifying and deleting dead objects) is concerned with memory issues and not resource issues. Hence if running on a PC with a few gigabytes of free RAM, it may wait an hour or two before even getting out of bed!1. GC进行收集是由内存状况决定的,而不是你的对象里的其他宝贵的系统资源。所以如果你的pc还有很多free的内存,你的对象可能会等一两个小时才被收集。2.There is no guarantee that the destructor will ever get called, even once memory is released.2. 就算内存被收集,你的析构函数也不一定会被调用。The last point is very important – due to the complexities of automatic garbage collection, you can’t rely on destructors, and this is an inherent limitation in the CLR.最后一条很重要,由于GC的复杂性,你不能完全依靠析构函数。这是CLR的先天缺陷。While destructors do not work properly, memory management does. You can be sure that the memory belonging to an orphaned object will always be released, even though its destructor may never be called.虽然析构函数不一定能很好的运行,内存管理是没有问题的,就算析构函数不被调用,对象占用的内存一定会被释放。
    So how do we get our textbox to disappear off the screen when we’re done with it? Well, firstly, our example was pretty artificial. In reality, we would have put the textbox control on a form in order to make it visible it in the first place. Assuming myForm was created earlier on, and is still in scope, this is what we’d typically do:现在看看当我们不需要textbox时会发生些什么。我们把textbox加到一个form里面,也就是下面的调用:myForm.Controls.Add (myTextBox);
    As well as making the control visible, this would also give it another referee (myForm.Controls), so when the local reference variable myTextBox drops out of scope, we wouldn’t be in danger of losing the textbox. The other effect of adding it to the Controls collection is that the .NET framework will deterministically call a method called Dispose on all of its members the instant they’re no longer needed. And in this Dispose method, the control can release its Windows handle, as well as dropping the textbox off the screen.当我们令这个control可见时,就会给它一个引用(myForm.Controls)。就算myTextBox出了作用域,我们也不会丢掉它(textbox对象)。把它放进Controls集合的另一个作用是此后.NET framework 将在它(textbox对象)不再需要时调用它的Dispose方法。这样它就可以在从屏幕上消失的同时释放windows handle了。All classes descending from MarshalByRefComponent (including all Windows Forms controls) have a Dispose method. This method must be called when an object is no longer needed in order to release resources other than memory. There are two ways this happens:所有从MarshalByRefComponent继承来的class (包括 全部的 Windows Forms controls)都由Dispose方法。如果你的对象有不同于内存的资源要释放,这个方法必须被调用。调用可以通过两种方法实现:
     - manually (by calling Dispose explicitly)- 手动,就是直接调用Dispose
     - automatically: by adding the object to a .NET container, such as a Form, Panel, TabPage or UserControl. The container will ensure that when it’s Disposed, so are all of its members. Of course, the container itself must be Disposed (or in turn, be part of another container).- 自动:把对象加入一个.NET容器,比如Form, Panel, TabPage 或 UserControl。这些容器会在它们自身Dispose时调用所有成员的Dispose。
    In the case of Windows Forms controls, we nearly always add them to a container – and hence rely on automatic disposal.上面的例子,我们把textbox加入一个容器,所以它会自动dispose。A Windows Forms Example
    Let's look a couple more types you’ll come across often in Windows Forms applications. Size is a type used for representing a 2-dimensional extent and Font, as you would expect, encapsulates a font and its properties. You can find them in the .NET framework, in the System.Drawing namespace. The Size type is a struct – rather like Point, while the Font type is a class. We'll create an object of each:现在看看Win Form。例子里用到的类型,Size和Font能在System.Drawing namespace里找到。Size是struct,而Font是class。我们先分别创建他们:Size s = new Size (100, 100);     // struct = value type
    Font f = new Font (“Arial”,10);    // class = reference type此时s和f在stack里,f引用的对象在heap中
    and we’ll also create a form. Form is a class in System.WinForms namespace, and is hence a reference type.再建一个form,它在System.WinForms namespace里,是引用类型。Form myForm = new Form();
    To set the form's size and font, we can assign the objects s and f to the form via its properties:OK,把s 和 f赋给formmyForm.Size = s;
    myForm.Font = f;
    Don't get confused by the double usage of the identifiers Size and Font: now they are referring to members of myForm and not the Size and Font classes. This double usage is acceptable in C# and is applied extensively throughout the .NET framework.
    Here's what it now looks like in memory:(图,请到http://www.albahari.com/value%20vs%20reference%20types.html去看)As you can see, with s, we've copied over its contents, while in the case of f, we've copied over its reference (resulting in two pointers in memory to the same Font object). This means that changes made via s will not affect the form, while changes made via f, will [2].s被拷贝到form对象中去了。而form对象中的font只不过是f的一个拷贝,他们都是引用,指向同一个存在于heap中的对象。这样s的变化不会影响到form而f的变化会。In-Line AllocationPreviously we said that for structs, memory is usually allocated on the stack. But here is an exception: the newly copied Size struct is now on the heap - not as a separate object to which other variables reference, but as an integral part of its host object, in this case a form. This mode of storage is called "in-line". Fun with Structs
    We've made a slightly simplifying assumption in the diagrams in that Size and Font are depicted as fields in the Form class. More accurately, they are properties, which are facades for internal representations we don’t get to see. We can imagine their definitions look something like this:来看看当我们想改变一个form类的成员时会发生什么。class Form
    {
       // private field members   private Size size;
       private Font font;   // public property definitions   public Size Size {
          get  {return size;}
          set  {size = value; fire sizing events}
       }   public Font Font {
          get  {return font;}
          set  {font = value;}
       }
    }
    By using properties, the class has an opportunity to fire events when the form’s size or font changes. It provides further flexibility in that other size-related properties, such as ClientSize (the size of a control’s internal area without title bar, borders, or scroll bars) can work in tandem with the same private fields.Font和Size都被定义成propertyBut there is a snag. Suppose we want to double the form’s height, through one of its properties. It would seem reasonable to do this :不过有个问题,如果我们想把form的height放大1倍,那么好像应该这么做:myForm.ClientSize.Height = myForm.ClientSize.Height * 2;
    or more simply:或者这样更简单点:myForm.ClientSize.Height *= 2;
    While this compiles without error, it does absolutely nothing! What’s more, we get the same problem whether we use Size or ClientSize. Let’s look at why.可是这样做一点效果也没有。为什么哪?Imagine ClientSize as a public field rather than a property. The expression myForm.ClientSize.Height would then simply reach through the membership hierarchy in a single step and access the Height member as expected. But since ClientSize is a property, myForm.ClientSize is first evaluated (using the property’s get method), returning an object of type Size. And because Size is a struct (and hence a value-type) what we get back is a copy of the Form’s size. And it’s this copy whose size we double! Had Size been defined instead as a class, there would have been no problem, since ClientSize’s get method would have returned a reference, giving us access to the Form’s real size object.如果ClientSize 是一个public成员,那么这么做不会有什么问题。可是现在它时一个property。看看上面的表达式,首先调用get取ClientSize ,返回的时一个Size的对象。因为Size是一个struct,返回的时Size的一个拷贝。我们就是把这个值的拷贝放大了1倍。如果这种情况发生在一个class成员上,也不会有错,因为get返回的是一个引用的copy,也就是内存中真正的size对象。So how then do we change the form’s size? One way is to assign it a whole new object:只有象下面那样才能改变form的大小。myForm.ClientSize = new Size
     (myForm.ClientSize.Width, myForm.ClientSize.Height * 2);
    Fortunately, there is a SetClientSize method, which provides an easier and more efficient solution:也可以用SetClientSize 方法来做,这要简单多了myForm.SetClientSize (myForm.ClientSize.Width, myForm.ClientSize.Height);
    There’s more good news in that with most controls we usually size them via their external measurements (Size rather than ClientSize) and for these we also have ordinary integer Width and Height properties!大福音,部分control都用Size 而不是ClientSize来控制大小,所以没有这么麻烦。You might wonder if they could they have saved all this bother by defining Size as a class rather than a struct. But this would have two negative implications. Firstly, class objects have an extra storage and execution overhead in that they require a pointer, which must be de-referenced at runtime. This overhead, while quite small, is not desirable with a type so fundamental as Size or Point. Secondly, if Size was a class, its Height and Width properties would probably have been made read-only to avoid the complication of raising events when their values change. And as read-only properties, you would be forced to go about changing them by creating a new object – which is just what we wanted to avoid!-------------------------------------------------------------
    [1] This differs from the COM approach of reference counting, and avoids the problem of circular referencing
    [2] If it wasn’t for the niggling fact that the Font class is immutable, and so all its properties are restricted to being read-only!
      

  4.   

    class a{
       int i;
       b j=new b(this);
    }class b{
       a k=null;
       public void b(a v){
        this.k=v;
        k.i=10;
       }
    }上面的例子类a中new了一个类b,并将a的this指针,也就是它的引用作为参数。因此类b中可以操作a的变量i。
      

  5.   

    java是值传递,传进来的变量不可以改变值。
    但是要知道,对象和变量是完全不同的概念。变量不能改变值,但是对象的属性随你怎么改变。比如说,
    class A{
    ...
      String s="hello";
    }
    ...
    class B{
      void function(A a){
        a.s="Hello,world!";//这是对的,出去之后a.s的值确实改变了
        a=new A();//这样语法上也不错,但是出去之后a还是原来的a
      }
    }