Java 无法对Point类型的非静态方法进行静态引用

Java 无法对Point类型的非静态方法进行静态引用,java,Java,以下代码编译成功。但我只是在方法moveP的实现中,在其名称之前添加了static一词。在此之前,我遇到错误“无法对非静态字段moveP(PointForPassReferenceTypeParameterByValue)进行静态引用” 我的问题是为什么?我经过的物体是静止的?我的意思是静态引用在这里意味着什么? 如果我将调用moveP(p)替换为p.moveP(p),该怎么办 我会给你一个答案,这需要一些时间,所以继续检查回来,大约一个小时左右(或者检查我所有的保存,因为格式和东西让我发疯…)

以下代码编译成功。但我只是在方法moveP的实现中,在其名称之前添加了static一词。在此之前,我遇到错误“无法对非静态字段moveP(PointForPassReferenceTypeParameterByValue)进行静态引用” 我的问题是为什么?我经过的物体是静止的?我的意思是静态引用在这里意味着什么? 如果我将调用moveP(p)替换为p.moveP(p),该怎么办


我会给你一个答案,这需要一些时间,所以继续检查回来,大约一个小时左右(或者检查我所有的保存,因为格式和东西让我发疯…)

首先,你的代码没有按照你发布的方式编译。小心地告诉社区它在运行,但它实际上并不运行。再加上其他帖子的重复应用,你的问题被贬低了

这是您的代码的第一个版本,只做了一个非常小的更改,允许它运行:

    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){
            PointForPassReferenceTypeParametersByValue p = new PointForPassReferenceTypeParametersByValue(2, 3);
            System.out.println("The new X and Y postions of the point P after it has been moved by the method p.moveP() are X: " + moveP(p).xPosition + " and Y: " + moveP(p).yPosition + ".");
        }

        public static PointForPassReferenceTypeParametersByValue moveP(PointForPassReferenceTypeParametersByValue del_p){
            del_p.xPosition=10;
            del_p.yPosition=20;
            del_p = new PointForPassReferenceTypeParametersByValue(del_p.xPosition, del_p.yPosition);
            return del_p;
        }
    }

    /* Make sure to understand the difference class types
     * 
     * With "pulbic class...." you create a Top-Level class ("normal" java class) which has to reside in its own .java file 
     * So if you want to create a "public class MyClass" it MUST reside in a file MyClass.java. 
     * 
     * If you however want to define multiple classes whithin the same .java file what you need is a so called nested top level 
     * class. It is basicially the same like a top-level class except it is not stored within a own .java file with the same name 
     */
    class PointForPassReferenceTypeParametersByValue {
        int xPosition;
        int yPosition;
        PointForPassReferenceTypeParametersByValue(int x, int y){
            xPosition=x;
            yPosition=y;
        }

    }
在可读性方面对代码的第一个改进可能是将类和方法重命名为sencefull长度(字符),这样就不必横向滚动

现在,第二个问题是您试图归档的内容。我假设您只是尝试获取一个代码,其中有一个具有x/y位置的点和一个可以修改这些坐标的方法。通过上面的代码,你现在可以运行了

然而,这里有一个版本id更喜欢以下与语言无关的面向对象编程概念,如封装和其他(这些概念值得一读,然后将在Java、.NET、C#等中使用)

好的,我们现在所做的就是所谓的重构,它将引导我们找到一个更易于理解、维护的代码,并且在运行时具有更高的性能

我们一步一步地这样做。第一步是通过创建 更好的版本,你以前的实现的东西,基本上是一个点

    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){
            MyPoint p = new MyPoint(2, 3);
            //We already use the get/ set methods rather to "rape" your new MyPoint object by directly calling its member variables
            System.out.println("The new X and Y postions of the point P after it has been moved by the method p.moveP() are X: " + moveP(p).getXPosition() + " and Y: " + moveP(p).getYPosition() + ".");
        }

        public static MyPoint moveP(MyPoint del_p){
            del_p.setXPosition(10);
            del_p.setYPosition(20);
            del_p = new MyPoint(del_p.getXPosition(), del_p.getYPosition());
            return del_p;
        }
    }


    /* We call this MyPoint just because the sun is shining bright outside here in switzerland (teaching you how to name things properly 
     * exceeds the bounds of my answer right now. 
     */
    class MyPoint {
        /* Encapsulation: You dont want other classes to directly access your class members (variables) so you define those 
         * as private. Thus to allow other classes to access those private members you provide get/set Methods. Go read about
         * the java bean naming convention of bean propertys and the according get/ set methods right now and make sure to always
         * use that naming pattern in the future (since tonns of frameworks youre maybe using in the future will rely on you following 
         * those standards
         */
        private int xPosition;
        private int yPosition;

        MyPoint(int x, int y){
            xPosition=x;
            yPosition=y;
        }

        /* You dont want to have that for any variable in general but for those that should be accessable (indirectly) from 
         * outside your code. 
         */
        public void setXPosition(int xPosition){
            /* Because you now have two variables (read about visibility of different variable types) with the same name you have 
             * to clearify which of both you mean. By adding 'this' you tell the compiler youre talking about the variable of the
             * object rather than the local one of this method. 
             */

            this.xPosition = xPosition;
        }

        public int getXPosition(){
            /* Here you dont need the 'this' because there is no other local variable with the same name, you can however always 
             * make that clearification so "return this.xPosition" is equal in that case. 
             */
            return xPosition;
        }

        //The same for the yPosition value:
        public void setYPosition(int yPosition){
            this.yPosition = yPosition;
        }

        public int getYPosition(){
            //like told above 'return this.yPosition' is equal to 'return yPosition'
            return this.yPosition;
        }

    }
在第二步中,我们想看看修改点的方法。这里有两种可能是您想要归档的内容(当然还有更多,但我选择了两种通用方法),因此有两种方法:

    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){
            MyPoint p = new MyPoint(2, 3);

            System.out.println("The new X and Y postions of the point P after it has been moved by the method p.moveP() are X: " + moveThePointYouDeliverMe(p).getXPosition() + " and Y: " + moveThePointYouDeliverMe(p).getYPosition() + ".");

            System.out.println("The new X and Y postions of the new point P after it has been created by the method p.moveP() are X: " + moveThePointYouDeliverMe(p).getXPosition() + " and Y: " + moveThePointYouDeliverMe(p).getYPosition() + ".");

        }

        /* If you just want to move a point and not create a new, independent (of the one delivered) one you 
         * can just use the set-methods of that point, modify its values and return the updated point.
         * This will best match your above System-out which indicates you still have the same Point object you delivered to that method.
         */
        public static MyPoint moveThePointYouDeliverMe(MyPoint del_p){
            del_p.setXPosition(10);
            del_p.setYPosition(20);
            return del_p;
        }

        /* If you dont want to change the object delivered to your method but rather return a new, independent object
         * your previous approach comes in with a little modification so you dont change the state of the delivered object
         */    
        public static MyPoint copyAndMoveThePointDeliveredMe(MyPoint del_p){
            return new MyPoint(10, 20);
        }
    }


    /* We call this MyPoint just because the sun is shining bright outside here in switzerland (teaching you how to name things properly 
     * exceeds the bounds of my answer right now. 
     */
    class MyPoint {
        /* Encapsulation: You dont want other classes to directly access your class members (variables) so you define those 
         * as private. Thus to allow other classes to access those private members you provide get/set Methods. Go read about
         * the java bean naming convention of bean propertys and the according get/ set methods right now and make sure to always
         * use that naming pattern in the future (since tonns of frameworks youre maybe using in the future will rely on you following 
         * those standards
         */
        private int xPosition;
        private int yPosition;

        MyPoint(int x, int y){
            xPosition=x;
            yPosition=y;
        }

        /* You dont want to have that for any variable in general but for those that should be accessable (indirectly) from 
         * outside your code. 
         */
        public void setXPosition(int xPosition){
            /* Because you now have two variables (read about visibility of different variable types) with the same name you have 
             * to clearify which of both you mean. By adding 'this' you tell the compiler youre talking about the variable of the
             * object rather than the local one of this method. 
             */

            this.xPosition = xPosition;
        }

        public int getXPosition(){
            /* Here you dont need the 'this' because there is no other local variable with the same name, you can however always 
             * make that clearification so "return this.xPosition" is equal in that case. 
             */
            return xPosition;
        }

        //The same for the yPosition value:
        public void setYPosition(int yPosition){
            this.yPosition = yPosition;
        }

        public int getYPosition(){
            //like told above 'return this.yPosition' is equal to 'return yPosition'
            return this.yPosition;
        }

    }
现在,我们以“通用”的方式查看您的代码,因为像这样它很糟糕。这两种方法都只是设置静态值,但您希望允许其他人(在本例中包括您自己)以更通用的方式使用MyPoint类。所以我们允许他们告诉我们点必须移动到的新坐标

    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){

            MyPoint p = new MyPoint(2, 3);

            System.out.println("Created a Point with coordinates X="+p.getXPosition()+" , Y+"+p.getYPosition());

            int newXPos = 20;
            int newYPos = 10;

            System.out.println("Moving the Point to the new coordinates X="+newXPos+" , Y="+newYPos);

            /* Since you already have a reference 'p' to your point and know that your move-method wont change the reference (e.g. create and return a new 
             * Point Object. you can just call this method without storing the same reference:
             */
            moveThePointYouDeliverMe(p, newXPos, newYPos);

            System.out.println("The point was moved! New coordinates: X="+p.getXPosition()+" , Y+"+p.getYPosition());           

        }

        /* We now allow the outerworld to tell  us where to move that point to.
         */
        public static MyPoint moveThePointYouDeliverMe(MyPoint del_p, int newXPosition, int newYPosition){
            del_p.setXPosition(newXPosition);
            del_p.setYPosition(newYPosition);
            return del_p;
        }

        /* We dont need such a method because the outerworld can already create the same result by directly calling 
         * the constructor of MyPoint providing the values of x/y to the constructor
         * 
         * So delte this comment and this method 
         */    
        /*public static MyPoint copyAndMoveThePointDeliveredMe(MyPoint del_p, int newXPosition, int newYPosition){
            return new MyPoint(newXPosition, newYPosition);
        }*/
    }


    /* We call this MyPoint just because the sun is shining bright outside here in switzerland (teaching you how to name things properly 
     * exceeds the bounds of my answer right now. 
     */
    class MyPoint {
        /* Encapsulation: You dont want other classes to directly access your class members (variables) so you define those 
         * as private. Thus to allow other classes to access those private members you provide get/set Methods. Go read about
         * the java bean naming convention of bean propertys and the according get/ set methods right now and make sure to always
         * use that naming pattern in the future (since tonns of frameworks youre maybe using in the future will rely on you following 
         * those standards
         */
        private int xPosition;
        private int yPosition;

        MyPoint(int x, int y){
            xPosition=x;
            yPosition=y;
        }

        /* You dont want to have that for any variable in general but for those that should be accessable (indirectly) from 
         * outside your code. 
         */
        public void setXPosition(int xPosition){
            /* Because you now have two variables (read about visibility of different variable types) with the same name you have 
             * to clearify which of both you mean. By adding 'this' you tell the compiler youre talking about the variable of the
             * object rather than the local one of this method. 
             */

            this.xPosition = xPosition;
        }

        public int getXPosition(){
            /* Here you dont need the 'this' because there is no other local variable with the same name, you can however always 
             * make that clearification so "return this.xPosition" is equal in that case. 
             */
            return xPosition;
        }

        //The same for the yPosition value:
        public void setYPosition(int yPosition){
            this.yPosition = yPosition;
        }

        public int getYPosition(){
            //like told above 'return this.yPosition' is equal to 'return yPosition'
            return this.yPosition;
        }

    }
因为borring与我们的老板们的会面,他们和你一样有软件工程方面的知识,只是endet和我必须回到这里工作,这是一个没有评论的最终版本。最后一步是让您的点提供一种移动自身的方法,而不是让代码允许移动交付的点(也可以):

我完全不知道这是否对你有帮助,以防万一,我就是这样开始学习java的。在您完全理解并正确使用静态上下文之前,这是一种摆脱静态上下文的简单方法:

    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){
            new PassReferenceTypeParamenterByValue().myDynamicMain();       
        }

        public void myDynamicMain(){
            //Look at this as your new main for now until you understand the static parts in the java world.
            System.out.println("From here on i dont have to care about static stuff...");

            //Place your Code here 
        }
    }
顺便说一句,这就是我学习java并成为一名相当受欢迎的软件开发人员的过程,在java方面有10年以上的经验(仅仅是可以接受的英语技能……不,对不起,我知道这很可怕)

  • 我有一本589页的书,书名是“从初学者到专业人士学习Java”
  • 在我成为那本书的头两年里,我不断尝试像你这样的事情,并试图完全理解它们为什么有效或为什么无效
  • 两年后,我已经完整地读了那本书20多次了

现在是我回去工作的时候了,祝你在学习java的过程中好运和快乐

请阅读-并查看右侧的所有“相关”问题。参考这篇文章,首先阅读静态和非静态之间的区别。不要删除我对荒谬类名的评论,不管是谁做的。这是一个合理的评论:它们是理解的巨大障碍。你是否评价或接受这个答案是出于我的兴趣。但是一旦你成为一名优秀的程序员,记住要帮助刚开始的人;)感谢您的广泛回答,其中包括一些指导。我非常感激。我很感激你,我会记住你的建议,你现在正在帮助我,如果我能帮助别人,那就是我的回报:)我也会去找你推荐的那本书。再次感谢。祈祷。你能告诉我这本书的作者的名字吗?不客气!这是我在2003年或2004年使用的书:不确定同一家书店是否有更新的书。与本书无关,确保不要像第二章那样陷入困境,因为你不理解每一个被剪掉的句子/代码。我犯了这个错误,浪费了很多时间。结果表明,最好是反复阅读整本书(前10次我跳过了java security之类的章节),因为每次我都因为练习而理解得更多。我想这本书是德语版的,你是用德语版的还是用英语读的(我不知道是否有英语版)
    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){

            MyPoint p = new MyPoint(2, 3);

            System.out.println("Created a Point with coordinates X="+p.getXPosition()+" , Y+"+p.getYPosition());

            int newXPos = 20;
            int newYPos = 10;

            System.out.println("Moving the Point to the new coordinates X="+newXPos+" , Y="+newYPos);

            p.moveMe(newXPos, newYPos);

            System.out.println("The point was moved! New coordinates: X="+p.getXPosition()+" , Y+"+p.getYPosition());           

        }
    }

    class MyPoint {

        private int xPosition;
        private int yPosition;

        MyPoint(int x, int y){
            xPosition=x;
            yPosition=y;
        }

        /* Like polite people polite programms ask things to move rather to just move them away not because the result differs 
         * but the way you got to the result :) 
         */
        public void moveMe(int newXPos, int newYPos){
            /*We own those variables, we have the exclusive right to directly modify those values and are the only ones that dont 
             * need to call the set/get Methods for this
             */
            this.xPosition = newXPos;
            this.yPosition = newYPos;
        }

        public void setXPosition(int xPosition){
            this.xPosition = xPosition;
        }

        public int getXPosition(){
            return xPosition;
        }

        public void setYPosition(int yPosition){
            this.yPosition = yPosition;
        }

        public int getYPosition(){
            return this.yPosition;
        }

    }
    public class PassReferenceTypeParamenterByValue {

        public static void main (String []args){
            new PassReferenceTypeParamenterByValue().myDynamicMain();       
        }

        public void myDynamicMain(){
            //Look at this as your new main for now until you understand the static parts in the java world.
            System.out.println("From here on i dont have to care about static stuff...");

            //Place your Code here 
        }
    }