天天进步一点点,距离大腿又近一步! 阅读本文大概须要9分钟
如下题目是从面试经历和常考面试题中选出有点儿意思的题目,参考答案若有错误,请联系小编指正,感谢!
1.1定义
JAVA反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意一个方法。java
1.2做用
①在运行时判断任意一个对象所属的类
②在运行时构造任意一个类的对象
③在运行时判断任意一个类所具备的成员变量和方法(经过setAccessible()方法可访问或修改private成员)
④在运行时调用任意一个对象的方法面试
1.3用法
首先得获取class字节码对象,再经过class对象可获取类中的各类属性和方法等
3种获取class对象方法:
1.经过Object类的getClass方法spring
Class clazz = foo.getClass();
2.经过对象实例方法获取对象数据库
Class clazz = foo.class;
3.经过Class.forName方式数组
Class clazz = Class.forName("xx.xx.foo");//完整的类名,包括所在包
例子:安全
public class User { private String name; private int age; private void speak(String name){ System.out.println("个人名字是:"+name); } public User(String name,int age)) { this.name = name; this.age = age; } } User user = new User("张三",25); // 获取User类中的全部方法 Method[] methods = User.class.getDeclaredMethods(); // 获取User类中的全部属性 Field[] fields = User.class.getDeclaredFields(); //遍历User类的全部属性 for (int i = 0; i < fields.length; i++) { fields[i].setAccessible(true); System.out.println(fields[i].getName()+":"+fields[i].get(user)); }
结果:多线程
name:张三
age:25
(反射基本上能够获取类中全部的信息,请自行谷歌)工具
1.4优缺点
优势:
1.可以运行时动态获取类的实例,大大提升了系统的灵活性和扩展性;
2.与java动态编译相结合,能够实现无比强大的功能。
缺点:
1.使用反射的性能较低;
2.使用反射来讲相对不安全;
3.破坏了类的封装性,能够经过反射来获取这个类的属性和私有方法。性能
String:字符串常量,对象一旦建立,不可更改
StringBuilder和StringBuffer:字符串变量,对象可更改ui
不是线程安全的操做。它涉及到多个指令,如读取变量值,增长,而后存储回内存,这个过程可能会出现多个线程交差。
Object类默认的实现以下:
public boolean equals(Object obj) { return (this == obj); }
默认的实现只有当对象和自身进行比较时才会返回true, 这个时候和 “==”是等价
的。
Java中不少类(String类 Date类 File类)等都对equals方法进行了重写,这
里拿常见的String类
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
这里,从String的重写equals方法能够看出,比较的是String的所存放内容是否相等
equals方法实际上是交给开发者重写,在自定义类里,你想用它比较什么均可以,只要你重写它,因此咱们并不能单纯的说它是用来比较什么的
**读前须知:
栈:存放对象引用
堆:存放全部new出来的对象和数组**
数组能够存放基本数据类型,能够存放引用类型。数组的引用存放于栈中,实际存放的对象在堆中。
可看如下代码及分析:
// 存放基本数据类型 int[] arr = new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3; // 存放自定义类型User User[] userArr =new User[3]; User user1 = new User("张三"); User user2 = new User("李四"); user[0] = user1; user[1] = user1; user[2] = user2;
运行步骤分析:
存放基本数据类型
1.在栈中建立arr引用
2.在堆中建立长度3的int数组,并将其初始化,赋默认值0
3.将arr引用指向int数组
4.对int数组中每个int值从新赋值
存放引用类型User
1.在栈中建立userArr引用
2.在堆中建立长度3的User数组,并将其初始化,赋默认值null
3.将userArr引用指向User数组
4.在栈中建立user1,user2引用
5.在堆中建立User("张三"),User("李四")对象
6.将user1,user2分别指向User("张三"),User("李四")
7.分别对User数组中的每个User进行从新赋值,此时user[0]指向User("张三"),user[2]指向User("张三"),user[2]指向User("李四")
ps:这里所说的指向是引用变量指向对象,即引用变量保存了对象在堆内存中的存储地址
可看下图,更好的理解:
图片描述
ps:数组所存放的基本数据类型可能存放于堆中,也可能存放于方法区的常量池中,此处仅以堆中的基本数据类型为例。
后台回复"谷歌访问助手",获取插件访问谷歌,沉入信息的海洋
**end~thanks!欢迎关注公众号"java从心"一个立志成大腿而天天努力奋斗的年轻人期待你的到来!**