java初学者易犯的错误及注意事项(持续更新)

1.将一个java源文件编译成字节码文件后再将源文件删除会影响字节码文件的执行吗?

在这个过程中,一旦.java文件被编译成.class文件,.java文件就不再是执行程序所必需的。.class文件包含了执行程序所需的所有信息,只要.class文件还在,程序就可以被JVM执行,而不需要原始的.java文件。

因此,将.java源文件删除后,只要.class字节码文件还在,并且相关的依赖库也都可用,那么编译后的程序就可以正常执行。这也是Java程序“一次编写,到处运行”这一特性的体现之一,因为JVM能够在任何支持它的平台上执行相同的字节码文件。

2.一个java源文件中最多只能有一个public类,该java源文件名必须与public类名相同。

3.一个java源文件可以有很多其他非public类型的类,也可以将main方法写在非public类中,然后指定运行该非public类。编译后,每一个类都对应一个.class文件

4.System.out.println("1

                                  2

                                  3");不能实现换行,反而会报错

5.System.out.println(“”)要输出两个反斜杠要写\\\\

6.System.out.println(“12345\r67”);输出结果为67345(在不同编译器结果可能有不同)

7.多行注释里面不允许有多行注释嵌套。类、方法的注释要以javadoc的方式书写。源文件最好用utf-8编码

8.String类首字母要大写

9.System.out.println(“100”+98);输出10098,当+两方有一边是字符串时做拼接运算

System.out.println(“100”+98+3);输出100983

System.out.println(100+98+“1”);输出1981

System.out.println(100+1+‘a’)输出198

10.java各整数,浮点数类型有固定的范围和字段长度,不受具体的操作系统的影响以保证java的可移植性

11使用long的正确方法 long x=10L;数字后加L

12.java的浮点类型默认为double型,若要使用float,要在数字后面加F

0.52有时也可表示为.52小数点不能掉。浮点数的位数过高时采用截尾而不是四舍五入

13。double num=8.1/3;System.out.println(num);结果为2.69999999999997.因此对运算结果为小数的表达式进行比较时要注意,最好是以两个数的差值的绝对值在某个精读范围内进行判断

14.字符类型可以直接存放一个数字例如char c=97;输出变量c的结果是a(unicode码,两个字节)

char类型变量用单引号。在java中,char类型的本质是一个整数,并且支持运算

15.布尔类型变量用boolean表示,不可以用0或者非0的数表示真假(与c不同),只能用true或者false表示

16.自动类型转换,char->int->long->float->double,另一条路线byte->short->int->long->float->double只要是低向高转换都可以。有多重混合类型的数据进行运算时,系统优先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。(byte,short)和char不会互相转换,但是它们三者可以进行运算,在运算时先转为int类型(注意byte+byte的结果是int类型)。布尔类型不参与转换

17.强制类型转换,自动类型转换的逆过程,将容量大的数据转为容量小的。使用小括号,只对最近的操作数有效。char类型可以保存int的常量值,但不能保存变量值,需要强转。char m=100;正确但int n=100;char m=n;错误

18

以下是一些基本数据类型与String类型之间互相转换的方法:

  1. 使用String.valueOf()方法

    这是转换基本数据类型到String的通用方法。

     

    java复制代码

    int number = 10;
    String strNumber = String.valueOf(number);
    System.out.println(strNumber); // 输出: 10
  2. 使用+操作符(字符串连接)

    任何数据类型与字符串使用+操作符时,都会触发字符串连接操作,从而隐式地将非字符串类型转换为String。

     

    java复制代码

    int number = 10;
    String strNumber = "" + number;
    System.out.println(strNumber); // 输出: 10
  3. 使用包装类的toString()方法

    基本数据类型都有对应的包装类(如Integer, Double等),这些包装类提供了toString()方法,可以返回基本数据类型值的字符串表示。

     

    java复制代码

    int number = 10;
    String strNumber = Integer.toString(number);
    System.out.println(strNumber); // 输出: 10

  1. 使用包装类的parseXxx()静态方法

    对于每种基本数据类型,其对应的包装类都提供了parseXxx(String s)静态方法,用于将字符串转换为对应的基本数据类型。注意,如果字符串格式不正确,这些方法会抛出NumberFormatException

     

    java复制代码

    String strNumber = "10";
    int number = Integer.parseInt(strNumber);
    System.out.println(number); // 输出: 10
    String strDouble = "3.14";
    double doubleValue = Double.parseDouble(strDouble);
    System.out.println(doubleValue); // 输出: 3.14
  2. 使用Character.forDigit()方法(针对char

    如果你需要将单个字符('0'-'9')的字符串表示转换为对应的int值,可以使用Character.forDigit()方法。

     

    java复制代码

    String charStr = "5";
    int charValue = Character.forDigit(charStr.charAt(0), 10); // 第二个参数是基数,这里使用10进制
    System.out.println(charValue); // 输出: 5
  3. 使用Boolean.parseBoolean()(针对boolean

    对于boolean类型,可以使用Boolean.parseBoolean(String s),但这个方法只接受字符串"true"作为返回true的输入,其他任何值(包括"false")都返回false

     

    java复制代码

    String boolStr = "true";
    boolean boolValue = Boolean.parseBoolean(boolStr);
    System.out.println(boolValue); // 输出: true

注意,在转换过程中需要谨慎处理异常和边界情况,特别是在使用parseXxx()方法时。

19.

int i=1;
i=i++;
System.out.println(i);结果为1(c语言也是1)

原因:使用了临时变量先令temp=i然后i++;然后i=temp

20

在Java中,短路与符号(&&)和逻辑与(&)都用于对两个布尔表达式进行逻辑与操作,但它们之间存在关键的区别

  • 短路与(&&:当使用&&对两个布尔表达式进行运算时,如果第一个表达式的结果为false,那么整个表达式的结果就确定为false,此时不会再去计算第二个表达式的值。这种特性被称为“短路”或“短路求值”。短路与主要用于提高程序的效率,特别是在第二个表达式的计算开销较大或者可能引发异常时。
  • 逻辑与(&:相比之下,使用&时,无论第一个表达式的结果如何,第二个表达式都会被计算。即使第一个表达式的结果是false,第二个表达式仍然会被执行。这意呀着,&不会短路,它会完整评估两个表达式的值

开发中一般使用短路与,效率高。短路或同理

21.逻辑异或a^b,a和b不同时结果为true

22.byte b=2;b=b+2;//错误byte b=2;b+=2//正确,等价于b=(byte)(b+2);即复合赋值运算符会进行类型转换
23.一些标识符命名规范:1.包名:多单词组成时所有字母都小写   2。类名,接口名:多单词组成时,所有单词的首字母大写3.变量名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写4.常量名:所有字母大写,多单词时用下划线连接

24,java获取用户输入使用next方法(与c语言不同),

import java.util.Scanner;Scanner s=new Scanner(System.in);
String name=s.next();//还有nextInt()等

25.在 Java 中,算数右移(>>)在移位时保持符号位不变,而逻辑右移(>>>)无论符号位是何值,高位都补 0 。

26.switch语句中执行case1后如果没有break语句则直接执行case2中代码而不是判断是否等于case2的值。表达式数据类型,应和case后的常量类型一致,或者是可以自动转换成可以互相比较的类型,比如输入的是字符,而常量是int。表达式的返回值类型必须是(byte,short,int,char,enum,string)

27.println会自动换行,print不会

28.break语句出现在多层嵌套的语句中时,可以通过标签指明要终止的是那一层语句块(与c++不同)label1:for(……){label2:for(……){break label1}}直接退出整个循环。在实际开发中尽量不要使用标签。continue也可以用label

29.数组中的元素可以是任意数据类型(包括基本类型和引用类型),但是不能混用。

数组创建后,如果没有赋值,则有默认值(int,byte,long,short都是0.double  float0.0.char\u0000   boolean false,string null)。数组是引用类型,是对象。

30.int[] arr1;int[] arr2=arr1;如果arr2变化会引起arr1变化,因为数组在默认情况下是引用传递,赋的值是一个地址,赋值方式为引用赋值,将arr1的地址赋值给arr2

31.在 Java 中,Arrays.sort()方法对于原始数据类型(如 int、double 等)是采用快速排序实现的,对于引用数据类型(如对象)则是采用归并排序实现的

32.java中数组长度允许用变量代替

Scanner s=new Scanner(System.in);
int x;
x=s.nextInt();
int[] arr=new int[x];

33.二维数组初始化 int a[][]=new int[][];

列数不确定初始化

Scanner s=new Scanner(System.in);

for(int i=0;i<arr.length;i++){

int x=s.nextInt();

arr[i]=new int[x];

for(int j=0;j<x;j++)

{arr[i][j]=s.nextInt();}}

java遍历二维数组for(int i=0;i<arr.length;i++)

{for(int j=0;j<arr[i].length;j++)

{代码块   }

}

34.二维数组在内存中的表示

35.对象在jvm内存的存在形式

36.对象的属性默认值与数组相同

p2=p1对象赋值时也是地址传递,同数组

37.java内存分区:1.栈:一般存放基本数据类型(局部变量)2堆:存放对象  3方法区:常量池和类加载信息(成员变量与方法)

38.java创建对象的流程分析:
Person p=new Person();

p.name="book";

p.age=18;//1.先加载Person类信息(属性和方法)。注意只会加载一次,当再创建一个p2对象时不会再加载2.在堆中分配空间,进行默认初始化,把地址赋给p

39.Person p1=new Person();

Person p2=p1;p2=null;System.out.println(p2.name);//会报错因为p2已经指向空

40

person p1;
p1.speak();//报错原因,p1没有初始化

41.在main方法中调用对象的成员方法时成员方法的栈与main方法的栈是两个不同空间,互相独立

42.方法的局部变量是互相独立的,不会互相影响,但如果使用的是引用类型变量,就会共享该引用类型的数据

43.方法重载:参数列表必须不同(参数类型或个数或顺序至少有一样不同),返回类型无要求,返回类型不构成重载的条件(与c++不同)

44.java允许将同一个类中多个同名同功能但参数个数不同的方法封装成一个方法,可以通过可变参数实现
例:class t{
public int sum(int... nums){int res=0; for(int i=0;i<nums.length;i++){res+=nums[i];}return res;}//使用可变参数时可以当数组来使用,即nums可以当做int型数组。可变参数的本质就是数组

注意:可变参数的实参可以是数组,但是不能一次性传入多个数组,比如t1.sum(a1,a2);会报错,而且也不能传多维数组。可变参数可以和普通参数一起放在形参列表,但必须保证可变参数放在最后,一个形参列表最多只能有一个可变参数

45.局部变量一般指成员方法中定义的变量,全局变量一般指类的属性,全局变量可以不赋值直接使用(因为有默认值),局部变量没有默认值因此必须赋值。

属性和局部变量可以重名,访问时遵循就近原则(实际开发不推荐),在同一作用域下,两个局部变量不能重名。局部变量只能在本类使用,属性可以通过对象在其他地方使用。局部变量不可以加修饰符

46.构造器的修饰符可以默认的。构造器没有返回值。方法名必须和类名一样(类似于c++)。构造器的调用是由系统完成的。构造器不是创建对象,而是初始化对象。

47this指针的本质是对象的一个隐藏属性,指向对象自己。

this就是表示当前对象,可以区分当前类的属性和局部变量。this不能在类定义的外部使用,只能在类定义的方法中使用。

48

调用当前类的成员方法

 

java复制代码

this.methodName(arguments);

这里的methodName是当前类中定义的一个方法名,arguments是调用该方法时传递的参数(如果方法需要参数的话)。虽然大多数时候调用本类的方法时可以不使用this,但在需要区分成员方法和局部变量或参数时,使用this可以明确指出是调用成员方法。

  1. 在构造方法中调用另一个构造方法(注意,这实际上是this的一个特殊用途):

     

    java复制代码

    public MyClass() {
    this(initialValue); // 调用另一个构造方法
    }
    public MyClass(int initialValue) {
    // 构造方法的实现
    }

    注意,这种调用必须在构造方法的第一行进行,且只能调用一次,而且只能在构造器中使用,不能在其他方法中使用。

  1. 避免无限递归:在调用成员方法时,要确保不会通过某种方式(比如条件语句错误)导致无限递归调用,这会最终导致栈溢出错误(StackOverflowError)。

  2. 正确使用this关键字:在大多数情况下,如果不需要区分成员变量和局部变量,或者不需要明确引用当前对象,可以不必显式使用this。但是,在需要明确指出意图或避免命名冲突时,使用this是一个好习惯。

  3. 构造方法中的this调用:如上所述,构造方法中使用this调用另一个构造方法时,必须作为构造方法的第一条语句,且只能调用一次。

  4. 静态上下文中不能使用this:由于this是对当前对象的引用,而在静态上下文中(如静态方法或静态初始化块中),不存在当前对象的概念,因此不能使用this

  5. this的返回值:虽然技术上this可以出现在返回类型为当前类类型的表达式中(比如在一个方法中返回this),但通常这种做法需要谨慎使用,确保这样做符合设计原则和预期用途。

使用this时,主要目的是增加代码的可读性和明确性,尤其是在处理复杂的类或具有多个重载方法的类中。

49.idea常用快捷键:1.sout快速输出System.out.println   2.ctrl+alt+L快速调整代码格式

3.alt+enter导入该行需要的类     4.alt+r快速运行程序 5.alt+insert生成构造器等6.自动分配变量名.var   7.fori模板完成循环(注:也可以自己设置模板)8.ctrl+b查看一个方法的源码

50.package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只能有一句package.
import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求

public修饰类可以跨包访问,默认只能同包访问

51子类继承了父类的所有属性和方法,但是私有属性不能在子类直接访问,要通过公共方法去访问。

当创建子类对象时,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作

super()和this()都只能放在构造器的第一行,因此二者不能同时存在于一个构造器

java中所有类都是object的子类。

子类最多只能继承一个父类,即java是单继承机制

C++和Java的多态机制在实现上存在一些关键的区别,这些区别主要体现在多态的实现方式、运行时行为以及编译时和运行时的处理上。以下是具体的区别:

  • C++:C++中的多态性主要通过虚函数(virtual functions)和继承(inheritance)来实现。当一个基类成员函数被声明为虚函数时,派生类可以通过覆盖(重写)这个函数来提供自己的实现。在运行时,通过虚函数表(Virtual Table, VTable)和虚函数指针(Virtual Table Pointer, VPtr)来动态确定调用哪个版本的函数。VTable和VPtr是在编译阶段由编译器自动生成的,存储在程序的二进制文件中。
  • Java:Java中的多态性也通过继承和重写方法来实现,但具体实现机制与C++有所不同。Java中的方法表(Method Table)是由Java虚拟机(JVM)在运行时动态生成的,而不是在编译时生成。当某个方法被调用时,JVM通过查找对象的方法表来确定要调用的具体方法。

  • C++:在C++中,多态的调用在编译时不会完全确定,而是在运行时根据对象的实际类型来确定。这意味着,如果有一个基类指针指向一个派生类对象,并通过该指针调用一个虚函数,那么实际调用的是派生类中覆盖后的函数版本。
  • Java:Java中的多态行为也是动态确定的,但与C++类似,也是在运行时通过查找方法表来实现。不过,由于Java是运行在JVM上的,因此方法表的生成和管理是由JVM来完成的,而不是像C++那样在编译时生成。

  • C++:在C++中,虚函数表和虚函数指针是在编译阶段由编译器生成的,并存储在程序的二进制文件中。这意味着在程序载入内存之前,这些信息就已经存在。此外,C++中的多态在构造函数中通常不会发生,因为子类在构造时,父类必须已经构造完成。
  • Java:Java中的方法表是在JVM将.class文件载入到内存中时动态生成的,并存储在JVM的方法区中。这意味着在编译时,.class文件中并不包含方法表的信息。此外,Java中的多态在构造函数中可以发生,这可能导致一些难以察觉的问题(如子类在父类构造函数中尚未完全构造时就被调用)。

  • 继承和多态的粒度:Java支持接口,而C++没有内置的接口概念(但可以通过纯虚函数和抽象类模拟)。Java中的接口提供了一种更为严格的多态实现方式,允许一个类实现多个接口。
  • 类型检查:Java在编译时会进行严格的类型检查,以确保类型安全。而C++在编译时的类型检查相对宽松,但在运行时可能会遇到类型不匹配的问题(如通过基类指针访问派生类特有的成员)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值