Java常见误区

前言
在学习Java之前我们要懂得一些Java的基础常识问题,如果一些细节不注意,你甚至连程序都无法运行,只能通过报错来查找问题,这样既考验了你的英文能力,又耽误了时间,所以,在学习之前需要弄清一些经常会遇到的错误。

常见错误1—主函数定义其他函数

初学者往往通过例子进行学习,而教材中有很多事例往往不会写完整,更不会为你创建一个类来给你演示。以下为常见的第一个错误,主函数定义其他函数
错误案例:
输出字符串"ok"

public class Test {
    public static void main(String[] args){
        public void Test(){
            System.out.println("ok");
        }
    }
}

java表达式不合法的开始 java中非法的表达式开始_java

报错为非法表达式开始,一般main函数为设定的主函数作为程序入口,每个类只有一个主函数,main函数用来创建实例化对象调用其他函数的并且执行其他函数,而不能用来创建函数,且方法里不能定义方法,只能在方法里定义一个类,再在这个类里再定义方法。

修改正确:
1.直接输出

public class Test {
    public static void main(String[] args){
        System.out.println("ok");
    }
}

结果:

java表达式不合法的开始 java中非法的表达式开始_构造函数_02


2.调用函数

// An highlighted block
public class Test {
    public static void main(String[] args){
        Test test=new Test();
        test.printTest();
    }
    public void printTest(){
        System.out.println("ok");
    }
}

结果也是一样

通过函数调用的方式我们只需要写一次输出的方法,以后想要使用的时候直接调用,不需要每次都要我们自己写输出的内容。

常见错误2—函数的返回类型(缺省类型、缺省返回值)

函数返回的作用

可能有人会想,为什么需要返回类型,直接定义直接用不就行了吗?这时我们就想,函数类型有哪些?

函数的常用类型有int型、String型、void型,其中int型返回函数的整数值,String型返回函数的字符串类型,void型,无类型返回的不是字符串或者数字,而是返回的需要执行的动作,上个例子中的printTest就是无类型函数,因为它只要执行的动作就行,没有返回数值。

缺省返回类型

通常情况下,如果函数不需要返回字符串或者数值,仅仅只提供执行的方法时,我们使用void表示无类型返回,但不可省略,否则报错

如:

java表达式不合法的开始 java中非法的表达式开始_构造函数_03


java表达式不合法的开始 java中非法的表达式开始_构造函数_04

缺省返回值return

说完了无返回类型的void,现在就讲有返回类型的String和int,我们发现,void类型的函数是没有返回值的,而其他有返回值的需要加上返回值类型

直接返回型:

public class Test {
    public static void main(String[] args){
        Test test=new Test();
        System.out.println(test.getName());
    }
    public String getName(){
        return "我叫小明";
    }
}

结果:

java表达式不合法的开始 java中非法的表达式开始_类_05


返回传递的参数类型:

public class Test {
    private String name;
    public static void main(String[] args){

        Test test=new Test();
        System.out.println("我叫"+test.getName("小明"));
    }
    //获取姓名,其中getName中的参数name来自与main函数实例化的参数,如"小明"。
    public String getName(String name){
        this.name=name;//this.name指类中定义的成员变量name,后面的name指外部传递的参数name,只不过是重名,所以用this区分,this.属性,指本类中定义的属性
        return name;
    }
}

结果与上面一致

假设省略return,程序能运行明吗?

java表达式不合法的开始 java中非法的表达式开始_java表达式不合法的开始_06


java表达式不合法的开始 java中非法的表达式开始_java表达式不合法的开始_07


可以看到报错缺少返回return,因为定义的是String类型的返回值类型,而最后却没有返回实际的字符串,只进行了name赋值却没有把值传出去,其他函数就没办法使用,所以定义的这样的函数就没有意义。

缺少返回值对于初学者来说是经常犯的错误,所以需要养成良好的编码习惯,在定义不是无参数返回类型时,直接把return加到方法体里,最后再加上具体的返回值。

常见错误3—在方法体里声明的变量前加private、public、static等修饰符

错误案例:

public class Test {
    //private int age=1;
    public static void main(String[] args){
        Test test=new Test();
        System.out.println(test.age);
    }
    public int getAge(){
        private int age=1;
        return age;
    }
}

java表达式不合法的开始 java中非法的表达式开始_类_08

java表达式不合法的开始 java中非法的表达式开始_java_09

我们可以看到,age开始在Test类内定义是没有问题的,然而改到getAge()方法里就会有两种报错:
1.不能在方法里声明private变量。
2.虽然将方法里面的private去掉,不会报第一种错误,但是主函数里也无法调用,因为在方法体里定义变量,此变量是局部变量,无法被类内其他方法调用,所以没有意义。

java表达式不合法的开始 java中非法的表达式开始_java_10


java表达式不合法的开始 java中非法的表达式开始_类_11

private等修饰符是使用在类的,在类中声明用private修饰的成员变量时,表示这个变量可以被类中的方法访问;若在方法体里声明private修饰的变量,那么这个变量的作用域就在本方法体里,从声明到方法体结束,所以不能在方法体里声明private变量,因为声明的变量本来就在方法体里,没有意义,其他的方法也无法使用到这个变量。

修改后:

public class Test {
    private String name;//1.类中声明一个变量可以被类中的方法访问
    public static void main(String[] args){

        Test test=new Test();
        test.setName("小明");
        System.out.println("我叫"+test.name);//4.使用实例化后本类的name值
    }
    public void setName(String name){
        this.name=name;//2.本类的值name等于实例化后传进来的name,若无法理解,请从实例化的test.setName("小明")理解,并代入函数。
    }
    public String getName(){
        return name;//3.返回本类的name值,此时本类的name已经从setName()赋值,所以可以直接获得该值。
    }
}

常见错误4—创建对象时构造函数不实例化

先看一个案例:

public class Test {
    private int age;
    private String name;
    public static void main(String[] args){
        Test test=new Test();
        test.Test("小明",18);
	System.out.println("name=:"+ test.name+"age=:"+test.age);
    }
    public Test(String name,int age){
        this.name=name;
        this.age=age;
    }
}

java表达式不合法的开始 java中非法的表达式开始_java_12

java表达式不合法的开始 java中非法的表达式开始_java_13


首先我们创建了一个构造函数Test,并且该构造函数有两个参数,按照我们前面的做法,创建实例化对象时需要先new一个对象,再实例化,于是就有Test test=new Test();但是到这一步报错,内容是实参和形参列表不同,这时你可能在想:我下一步正要这么做:test.Test(“11”,10);可是你还没让我这么做就报错,这是为何?

重要:什么是构造函数?
1.构造函数是一种特殊的方法,其方法名必须和类名一致。
2.构造函数没有返回值类型,更没有return。
3.创建对象时需要实例化参数列表
构造函数有什么用?
完成对象的初始化工作,即创建对象时,先调用构造函数,再调用其他函数。

所以,在创建对象时,需要将方法的参数列表也实例化。
修改后:

public class Test {
    private int age;
    private String name;
    public static void main(String[] args){
        Test test=new Test("小明",18);
        System.out.println("name=:"+ test.name+",age=:"+test.age);

    }
    public Test(String name,int age){
        this.name=name;
        this.age=age;
    }
}

运行结果:

java表达式不合法的开始 java中非法的表达式开始_Test_14

构造函数还有一个重要作用,就是创建对象时,总是先执行构造函数(不创建构造函数时会有一个默认的构造函数,其无参数,没有方法体),俗称初始化,初始化中可能有部分信息不被外部所知道,这就实现了对信息的隐藏。
如:

public class Test {
    public static void main(String[] args){
    Test test=new Test();
    test.normalTest();
    }
    public void normalTest(){
        System.out.println("我是普通方法,后执行我");
    }
    public Test(){
        System.out.println("我是构造函数,先执行我");

    }
}

执行结果:

java表达式不合法的开始 java中非法的表达式开始_java_15


可以看出,即使在创建对象时不调用构造函数,它也会先执行,而这也就实现了初始化,且这部分也可以执行一些不需要被外部所发现的内容,实现了隐藏信息的功能。

常见错误5—不规范的命名、缺失的注释

最后,我将这部分也算作是一个常见错误,且这部分错误是绝大多数人都会犯的错误,也是导致其他错误最多的原因。紊乱的代码、随意的命名、空缺的注释这些都是比较令人头痛的错误,希望,每个人从写的第一份代码时都养成一个好的习惯,不仅为了自己,也为了他人,如果这部分习惯养不好,我觉得没有继续进行下去的必要,好了今天就介绍了几个简单但经常会遇到的错误,最后,感谢大家的阅读,共同学习,共同成长。