java中需要注意的点:

1、java中char类型占用2个字节

2、返回类型不是方法的签名,即不允许两个只有返回类型不同的方法。

3、String类中使用private final char[] value存储字符串,所以不可变。Java9之后使用private final byte[] value

4、StringBuilder线程不安全,速度较快;StringBuffer线程安全,使用了同步锁

5、静态方法中无法使用非静态变量。

6、子类使用super()调用父类构造函数,如果没有指定,则会默认执行无参构造函数,如果父类定义了有参构造函数未定义无参构造函数,则会编译错误。

7、成员变量如果未赋予初值,会自动赋予默认值;局部变量不会自动赋值。被final修饰的需要显示赋值。成员变量放在堆内存,局部变量放在栈内存。

8、对象引用存放在栈内存中,对象实例存放在堆内存中。

9、java不可以通过方法将一个引用指向另一个实例对象。

10、foreach循环不能修改集合中的元素。应该是由于值传递。如果要循环修改数据,使用for循环。

11、Comparable接口方法为compareTo(),如TreeMap排序规则是使用对象默认的compareTo()方法,所以改变TreeMap排序规则可以通过重写该方法实现。Comparator接口一般是作为排序函数的参数。

12、接口和抽象类的区别:(1)接口的默认方法是public,所有方法不可以实现,而抽象类可以有非抽象方法;(2)接口中除了static、final变量,不能有其他变量,而抽象类不一定;(3)一个类可以实现多个接口,而抽象类中则不一定;(4)接口方法的默认修饰符为public,抽象方法可以有public,protected和default修饰符,不可以用private修饰;(5)抽象是对类的抽象,而接口是对行为的抽象,是一种行为的规范。jdk8中接口也可以定义静态方法,jdk9的接口可以定义私有方法。

13、final关键字总结:(1)修饰基本数据类型的变量,则其数值在初始化之后不可以改变;如果为引用类型的变量,则初始化之后不能再让其指向另一个对象。(2)final修饰的类不可以被继承,final类中的所有成员方法都会被隐式地指定为final方法;

14、异常处理不会执行finally语句的情况:(1)finally语句执行第一行就发生异常,其他行出现问题,还是得到执行;(2)前面的代码执行了System.exit(int)已退出了程序;若该语句在异常之后,仍会执行;(3)程序所在的线程死亡;(4)关闭CPU。

15、transient关键字修饰的变量无法被序列化。

16、获取键盘输入的常用方式:

1、通过Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();

2、通过BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();

17、为什么有了字节流,还要有字符流?

字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。

18、深拷贝和浅拷贝

(1)浅拷贝是对基本数据类型进行值传递,对引用数据类型进行引用传递的拷贝;

(2)深拷贝是对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。

19、equals方法

equals方法容易出现空指针异常,应使用常量或确定值的对象来调用equals。更推荐使用java.util.Objects#equals

Objects.equals(null,"yasuo")  //false

20、当使用自动装箱方式创建一个Integer对象时,当数值在-128~127时,将创建的对象缓存起来。内存只保存一份数据。(对象==会比较内存地址)

Integer x=3;
Integer y=3;
System.out.println(x == y);// true
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a == b);//false
System.out.println(a.equals(b));//true
Integer a = 1234;
Integer b = 1234;
System.out.println(a==b);//false

21、浮点数计算和比较应该使用BigDecimal,在使用BigDecimal时,为了防止精度丢失,推荐使用它的 BigDecimal(String) 构造方法来创建对象。

22、Arrays.asList()

将一个数组转化为List集合,但是转化后其底层还是数组,不可以使用修改集合的方法(add/remove/clear)

/**
 *返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,
 与Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
 */ 
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

Arrays.asList()体现的是适配器模式,只是转换接口,后台的数据仍是数组。

注意:该方法是泛型方法,传入的对象必须是对象数组。

int[] myArray = { 1, 2, 3 };
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));//数组地址值
System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException
int [] array=(int[]) myList.get(0);
System.out.println(array[0]);//1

当传入一个原生数据类型数组时,Arrays.asList() 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。可以用包装类型解决上述问题。

Arrays.asList() 方法返回的并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。

List myList = Arrays.asList(1, 2, 3);
System.out.println(myList.getClass());//class java.util.Arrays$ArrayList

23、正确的将数组转换为ArrayList:

List list = new ArrayList<>(Arrays.asList("a","b","c"));

//使用java8的stream
Integer[] myArray = {1,2,3};
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int[] myArray2 = {1,3,2};
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

//使用 Guava
//对于不可变集合,你可以使用ImmutableList类及其of()与copyOf()工厂方法:(参数不能为空)
List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array
//对于可变集合,你可以使用Lists类及其newArrayList()工厂方法:
List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

//使用 Apache Commons Collections
List<String> list = new ArrayList<String>();
CollectionUtils.addAll(list, str);

24、Collection.toArray()

该方法是一个泛型方法<T> T[] toArray(T[] a); 如果toArray方法中没有传递任何参数的话返回的是Object类型数组。

String [] s= new String[]{
    "dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A"
};
List<String> list = Arrays.asList(s);
Collections.reverse(list);
s=list.toArray(new String[0]);//没有指定类型的话会报错

25、不要在foreach循环中进行元素的remove/add操作。remove操作请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。(原因是java会将foreach循环翻译成Iterator迭代器)

//正确
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while(itreator.hasNext()){
    if(删除的条件){
        iterator.remove();
    }
}

//反例
for(String s:list){
    if(  ){
        list.remove(s);
    }
}

26、java 类中的main函数调用自身的方法需要通过类实例调用,直接调用只能够调用静态方法。



学习笔记      JAVA随笔

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!