成员变量和局部变量的区别
1.语法上:成员变量是属于类的,局部变量是在方法中定义的变量或者是方法的参数, 成员变量可以被public,private,static等修饰符修饰, 局部变量不能被访问控制修饰符修饰以及static修饰,但是两者都可以被final修饰。
2.变量存储上:成员变量如果使用static修饰,则它属于类的,如果没用static修饰,则变量是属于类的实例对象的。对象存在于堆内存,局部变量则存在于栈内存中。
3.从变量在内存中的生存时间上看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用自动消失。
4.成员变量如果没有被赋初值,则会自动以类型的默认值儿赋值(例外:被final修饰的成员变量必须显示的赋初值),而局部变量不会自动的赋值。
对象实体和对象的引用的区别
new创建对象实例(对象实例存在堆内存中),对象引用指向对象的实例(对象的引用放在栈内存中)。一个对象引用可以指向o个或者一个对象(一根绳子可以不系气球,也可以系住一个气球),一个对象实例可以有n个引用指向它(可以用n根绳子系住一个气球)。
构造方法有哪些特性:
面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写 equals 时必须重写 hashCode 方法?”
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在 JDK 的 Object.java 中,这就意味着 Java 中的任何类都包含有 hashCode() 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
我们先以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode: 当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与该位置其他已经加入的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()
方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的 Java 启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
通过我们可以看出:hashCode()
的作用就是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()
在散列表中才有用,在其它情况下没用。在散列表中 hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
我觉得如果别人问这个问题的话,回答不可变就可以了。下面只是给大家看两个有代表性的例子:
1) String 不可变但不代表引用不可以变
String str = "Hello";
str = str + " World";
System.out.println("str=" + str);复制代码
结果:
str=Hello World复制代码
解析:
实际上,原来 String 的内容是不变的,只是 str 由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已,也就是说多开辟了一块内存区域给"Hello World"字符串。
2) 通过反射是可以修改所谓的“不可变”对象
// 创建字符串"Hello World", 并赋给引用s
String s = "Hello World";
System.out.println("s = " + s); // Hello World
// 获取String类中的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
// 改变value属性的访问权限
valueFieldOfString.setAccessible(true);
// 获取s对象上的value属性的值
char[] value = (char[]) valueFieldOfString.get(s);
// 改变value所引用的数组中的第5个字符
value[5] = ‘_‘;
System.out.println("s = " + s); // Hello_World复制代码
结果:
s = Hello World
s = Hello_World复制代码
解析:
用反射可以访问私有成员, 然后反射出 String 对象中的 value 属性, 进而改变通过获得的 value 引用改变数组的结构。但是一般我们不会这么做,这里只是简单提一下有这个东西。
JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
反射是框架设计的灵魂。
在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。
举例:① 我们在使用 JDBC 连接数据库时使用 Class.forName()
通过反射加载数据库的驱动程序;②Spring 框架也用到很多反射机制,最经典的就是 xml 的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML 或 Properties 配置文件加载入内存中;2)Java 类里面解析 xml 或 properties 里面的内容,得到对应实体类的字节码字符串以及相关的属性信息; 3)使用反射机制,根据这个字符串获得某个类的 Class 实例; 4)动态配置实例的属性
原文:https://www.cnblogs.com/lwenm/p/12622246.html