likes
comments
collection
share

7 个 Java中的 棘手问题

作者站长头像
站长
· 阅读数 11

1、short+short不等于short

class Trick1 {

	public static short returnShort(short s) {
		return s;
	}

	public static void main(String[] args) {
		short s1 = 5;
		short s2 = 7;
		returnShort(s1 + s2);
	}
}

上面的代码看起来很简单,没有明显的错误,但实际上它无法编译。 编译错误是“方法 returnShort() 不适用于参数 int”。原因是在java中,两个short的和是一个int。

这称为二进制数字提升。

2、ArrayList 大小与 ArrayList 容量

public class Trick2 {

	public static void main(String[] args) {
		List<Integer> arr = new ArrayList<>(3);
		System.out.println("size 1 : " + arr.size());
		arr.add(1);
		arr.add(2);
		arr.add(3);
		arr.add(4);
		System.out.println("size 2 : " + arr.size());
	}

}

在此示例中,我们初始化一个容量等于 3 的 Integer 列表,然后向该列表添加 4 个元素。

预期的结果是什么?

代码编译时没有任何错误,并且输出显示“size 1 : 0 size 2 : 4”。

ArrayList 类有两个属性:

-Size:列表中元素的数量。

-Capacity:列表在不重新分配其内部结构的情况下可以包含的元素数量。

在我们的示例中,我们使用 ArrayList 构造函数来构造一个具有指定初始容量的空列表,然后如果我们添加的元素数量大于初始容量,它就会扩容。

3、具有相同值的两个字符串不能相等。

具有相同值的两个字符串不相等,因为它们引用不同的元素

public class Trick3 {
  
	public static void main(String[] args) {
		String s1 = "Hello";
		String s2 = "Hello";
		String s3 = new String("Hello");
		String s4 = new String("Hello");
		System.out.println(s1 == s2);
		System.out.println(s1 == s3);
		System.out.println(s3 == s4);
	}
	// true
	// false
	// false 
}

由于 Java 中字符串的不变性,JVM 可以通过在池中仅存储每个文字字符串的一份副本来优化为其分配的内存量。这个过程称为interning

当我们创建一个字符串变量并为其赋值时,JVM 会在字符串常量池中搜索相等值的字符串。 如果找到,Java 编译器将简单地返回对其内存地址的引用,而不分配额外的内存。 如果没有找到,它将被添加到池中并返回其引用。

4、是否应该设置无参数构造函数?

如果类中没有设置构造函数,那么 java 会创建一个默认构造函数,但是如果我们设置一个带有一个或多个参数的构造函数,则不会生成默认构造函数,如果需要,我们必须手动设置它。 所以规则是“如果你声明一个或多个构造函数,Java 不会为你创建一个隐式的 noargs 构造函数。”

5、包装类

float 值不会转换为 Double,因为 float 和 Double 完全不同; float 是原始类型,Double 是包装类。因此 float 值不满足 Double 的 isA 测试。

7 个 Java中的 棘手问题

尽管Integer整数是对象,但对象列表不接受INteger列表。 List 仅接受包含 Object 的 List,List 不满足 List 的 isA 测试,并且不会传递给 List 参数。

在使用泛型编程时,这是一个常见的误解,但它是一个需要学习的重要概念。

7 个 Java中的 棘手问题

6、引用类型的默认访问修饰符

如果没有为引用类型(类、枚举或接口)设置访问修饰符,则默认情况下它具有“包私有”访问权限。这意味着它只能在实现它的包内访问(它不是私有的或公共的)。

7、HashSet 可以等于 LinkedHashSet,尽管它们是两个不同的对象

public class Trick7 {

	public static void main(String[] args) {

		Set<String> set1 = new HashSet<>();
		set1.add("Hello");
		set1.add("World");

		Set<String> set2 = new LinkedHashSet<>();
		set2.add("Hello");
		set2.add("World");

		System.out.println(set1.equals(set2));
	}
	// true
}

HashSet 和 LinkedHashSet 扩展了 AbstractSet 类,因此它们继承了该类的 equals 方法。在官方实现中发现,如果给定对象也是一个集合,两个集合具有相同的大小,并且给定集合的每个成员都包含在该集合中,则此方法返回 true。这可确保 equals 方法在 Set 接口的不同实现中正常工作。一般来说,我们必须关注所使用的 equals 方法的实现。

如果喜欢这篇文章,点赞支持一下,关注我第一时间查看更多内容!