1.什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取类信息以及动态调用对象内容就称为java语言的反射机制

2.反射的作用

  • 在运行时判断任意一个对象所属的类;

  • 在运行时构造任意一个类的对象;

  • 在运行时判断任意一个类所具有的成员变量和方法;

  • 在运行时调用任意一个对象的方法;

3.反射的实现

 我们知道,要使用一个类,就要先把它加载到虚拟机中,生成一个Class对象。这个class对象就保存了这个类的一切信息。

反射机制的实现,就是获取这个Class对象,通过Class对象去访问类、对象的元数据以及运行时的数据。

有三种方法获得类的Class对象:Class.forName(String className)、className.class、实例对象.getClass();

4.什么是 Java 序列化?什么情况下需要序列化?

Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。

以下情况需要使用 Java 序列化:

  • 想把的内存中的对象状态保存到一个文件中或者数据库中时候;
  • 想用套接字在网络上传送对象的时候;
  • 想通过RMI(远程方法调用)传输对象的时候。

5.动态代理是什么?有哪些应用?

动态代理是运行时动态生成代理类。

动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java注解对象获取等。

6.怎么实现动态代理?

JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。

7.为什么要使用克隆对象?

在java中,我们使用对象的时候直接去new一个对象就好了,为什么还要克隆对象呢?

当我们new一个对象之后是要对该对象进行初始化的,不然这个对象是空的没有内容。而使用克隆,则会得到一个原对象以及原对象里面包含的内容。例如,你有一个User对象,里面的包含了相关的属性。此时你想要修改里面的某一属性,但又不想破坏原对象里面的数据,此时就可以克隆User这个对象,然后在克隆的这个User对象上进行修改操作。除此,如果你在操作完之后判断一下属性是否更改成功,则使用克隆的对象和原对象做一下对比即可。

8.如何克隆一个对象?

8.1浅复制

浅克隆就是把原对象中的一些属性值克隆过来。使用clone()方法进行浅克隆。但注意:必须要在被克隆类上实现Cloneable接口,并重写clone方法。若不没有实现该接口,则会抛出CloneNotSupportedException异常!

package interview;

public class CloneTest {

    public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
User user = new User();
user.setName("张三");
user.setAge(18);
System.out.println("原对象(user)的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge()+"\n"); // 对user对象进行克隆
User user1 = (User) user.clone();
// 查看一下克隆对象中的属性值
System.out.println("克隆后user1对象中的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge()+"\n"); // 结果和原对象中属性值相同 // 对user1对象进行修改
user1.setName("李四");
// 查看修改后的结果
System.out.println("user1对象进行修改后的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge()+"\n"); System.out.println("user1对象进行修改后user对象的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge()+"\n");
} } class User implements Cloneable {
private String name;
private int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}

从结果上可以看出,克隆对象user1和原对象user在修改属性数据时,两个对象之间的数据互不受影响。

那么如果后期需要调整代码,需要在原有的user对象中添加一个引用类型Address字段,那么克隆的user1对象会能受到影响吗?能和原对象user中的数据一致吗?

看下面代码演示,在原有基础代码上加入一个Address的类,并分别在User类和Address类中加入重写Object的方法。注意:User类中的引用address字段的权限修饰符为public,否则无法运行!

package interview;

public class CloneTest {

    public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
// 创建原对象,并为原对象中的属性进行赋值,然后打印出结果
Address address = new Address("中国", "山东");
User user = new User("张三", 18, address);
System.out.println("原对象(user)的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge() + ",地址为:" + user.getAddress() + "\n"); // 对user对象进行克隆
User user1 = (User) user.clone();
// 查看一下克隆对象中的属性值
System.out.println("克隆后user1对象中的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge() + ",地址为:" + user1.getAddress() + "\n"); // 对user1对象进行修改
user1.setName("李四");
user1.getAddress().setCity("北京");
// 查看修改后的结果
System.out.println("user1对象进行修改后的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge() +",地址为:" + user1.getAddress() + "\n"); System.out.println("user1对象进行修改后user对象的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge() + ",地址为:" + user.getAddress() + "\n");
} } class User implements Cloneable {
private String name;
private int age;
private Address address; public User(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
} // 定义一个address类
class Address {
private String country;
private String city; public Address(String country, String city) {
this.country = country;
this.city = city;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} @Override
public String toString() {
return "Address [country=" + country + ", city=" + city + "]";
} }

从结果上看,user1在克隆完后修改了姓名和地址值,修改后和原对象对比,发现姓名和地址的确发生了改变。但再次查看原对象的结果时,发现原对象的姓名值虽没变,但地址值却随着user1对象的改变而改变了!这样的话反而失去了克隆的意义。那么为什么会出现这种情况呢?因为浅克隆只是克隆原对象中的引用类型指向,并非克隆了原对象中的全部数据。

3.2 深克隆

深克隆和浅克隆的区别在于:浅克隆只克隆了原对象的引用类型的指向。深克隆则是克隆了原对象的所有。也就是说像上面案例所示,如果使两个对象之间互不影响,则使用深克隆。

深克隆的使用:在引用类型所在的类使其实现Cloneable接口,并使用public修饰符重写Clone()方法。

package interview;

public class CloneTest {

    public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
// 创建原对象,并为原对象中的属性进行赋值,然后打印出结果
Address address = new Address("中国", "山东");
User user = new User("张三", 18, address);
System.out.println("原对象(user)的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge() + ",地址为:" + user.getAddress() + "\n"); // 对user对象进行克隆
User user1 = (User) user.clone();
// 查看一下克隆对象中的属性值
System.out.println("克隆后user1对象中的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge() + ",地址为:" + user1.getAddress() + "\n"); // 对user1对象进行修改
user1.setName("李四");
user1.getAddress().setCity("北京");
// 查看修改后的结果
System.out.println("user1对象进行修改后的属性值:");
System.out.println("姓名为:" + user1.getName() + ",年龄为:" + user1.getAge() + ",地址为:" + user1.getAddress() + "\n"); System.out.println("user1对象进行修改后user对象的属性值:");
System.out.println("姓名为:" + user.getName() + ",年龄为:" + user.getAge() + ",地址为:" + user.getAddress() + "\n");
} } class User implements Cloneable {
private String name;
private int age;
private Address address; public User(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
// 这一步返回的这个user对象还只是一个浅克隆,
User user = (User) super.clone();
// 然后克隆的过程中获得这个克隆的user,然后调用这个getAddress()这个方方法得到这个Addrress对象。然后实现克隆。在设置到这个user中的Address。
// 这样实现了双层克隆使得那个Address对象也得到了复制。
user.setAddress((Address) user.getAddress().clone());
return user;
}
} // 定义一个address类
class Address implements Cloneable {
private String country;
private String city; public Address(String country, String city) {
this.country = country;
this.city = city;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} @Override
public String toString() {
return "Address [country=" + country + ", city=" + city + "]";
} @Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
} }

9.如何实现对象克隆?

  • 实现 Cloneable 接口并重写 Object 类中的 clone() 方法。
  • 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

java面试(反射)05的更多相关文章

  1. java面试-反射

    1.什么是反射?有什么优缺点?   反射就是动态加载对象,并对对象进行剖析.在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法.对于任意一个对象,都能够调用它的任意一个方法.这种动态获取信 ...

  2. Java面试3

    反射的定义: 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取它所有的成员变量和方法并且显示出来. 反射机制的 ...

  3. Java面试知识点汇总

    Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总   版权声明 ...

  4. Java面试:1

    月薪10000以上: 1.了解Java的反射机制 2. 了解泛型的原理 3. 了解Spring框架的基本原理 4. 熟悉设计模式 5. 了解如斐波那契数列之类的简单算法月薪20000以上: 1. 精通 ...

  5. 【应聘】阿里巴巴Java面试题目

    原文地址:http://blog.csdn.net/free0sky/article/details/7927275   一.String,StringBuffer, StringBuilder 的区 ...

  6. java 面试

        115个Java面试题和答案——终极列表(上) 本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力.下面的章节分为上下两篇,第一 ...

  7. Java面试系列

    如果你的面试简历是如下这样写的,请务必准备回答下面的所有问题. 面试职位:Java高级工程师 专业技能: (1)牢固掌握Java基础知识,如集合.并发.I/O等,并对Java源码有一定的研究. (2) ...

  8. Java面试指导

    Java面试指导   想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊 ...

  9. Java面试宝典

    相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消 ...

随机推荐

  1. 全面解读PHP-JS和jQuery

    一.变量的定义 1.未使用值来申明的变量,其值为 undefined. 2.如果重新声明一个变量,该变量的值不会丢失. //定义一个变量 var str = 'hello'; //重新申明 var s ...

  2. React组件库集锦及学习视频

    [转载]https://www.rails365.net/articles/react-zui-hao-de-ui-zu-jian-ku-ji-jin 这里有一篇讨论,说了哪个才是 React 最好的 ...

  3. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_01.SpringMVC概述及入门案例

    第二章 第三章 第四章 三层框架 springMvc是表现层

  4. sysstat功能列表

    iostat:统计并报告你的设备的CPU状态和I/O状态数据.mpstat:监控和显示关于CPU的细节信息.pidstat:统计正在运行的进程/任务的CPU.内存等信息.sar:保存和报告不同资源(C ...

  5. Linux监控命令之==>netstat

    一.命令说明 netstat 命令用于显示本机网络连接.运行端口.路由表等信息 二.参数说明 -a (all):显示一个所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连 ...

  6. Stream流实现斐波那契数列

    1.前言 我们都知道斐波那契数列有很多种实现方法,在jdk1.8以前没有流操作,只能通过递归或者迭代等其他方式来实现斐波那契数列, 但是jdk1.8以后,有了流操作,我们就可以使用流来实现斐波那契数列 ...

  7. elasticsearch mappings之dynamic的三种状态

    目录 前言 动态映射(dynamic:true) 静态映射(dynamic:false) 严格模式(dynamic:strict) 返回主目录 前言 回到顶部 一般的,mapping则又可以分为动态映 ...

  8. Doker部署Jmeter(一) 目标服务器部署Jmeter监控容器

    用jmeter插件监控服务器性能之前也有提到:https://www.cnblogs.com/betterbb/p/11285022.html 这里主要记录一下docker上的部署,所需的3个插件可以 ...

  9. 【HANA系列】【第八篇】SAP HANA XS使用Data Services查询CDS实体【二】

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第八篇]SAP HANA XS ...

  10. 【HANA系列】SAP 【第一篇】EXCEL连接SAP HANA的方法(ODBC)

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP [第一篇]EXCEL连接 ...