System.out.println(cls);
}
}
"class java.util.Date"
此时可以不使用import语句导入一个明确的类,而类的名称是采用字符串的形式进行描述的。
反射实例化对象
-------
当拿到一个类的时候,肯定要直接使用关键字new 进行对象实例化操作这属于我们习惯性的做法。如果拿到Class类对象,那么就可以做到利用反射来实例化对象操作:
public T **newInstance()** throws InstantiationException,IllegalAccessException
**范例:** 利用反射来实例化对象
/正常实例化/
class Book{
public Book(){
System.out.println("*** Book的构造方法 ***");
}
@Override
public String toString() {
return "--- 这是Book方法 ---";
}
}
public class ReflectTest6 {
public static void main(String[] args) throws ClassNotFoundException {
Book b = new Book();
System.out.println(b);
}
}
"*** Book的构造方法 ***
--- 这是Book方法 ---"
package com.jkx.lzh.test;
/*反射实例化*/
class Book{
public Book(){
System.out.println("*** Book的构造方法 ***");
}
@Override
public String toString() {
return "--- 这是Book方法 ---";
}
}
public class ReflectTest7 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException{
Class<?> cls = Class.forName("com.jkx.lzh.test.Book");
Object obj = cls.newInstance();
}
}
"*** Book的构造方法 ***"
class Book{
public Book(){
System.out.println("*** Book的构造方法 ***");
}
@Override
public String toString() {
return "--- 这是Book方法 ---";
}
}
public class ReflectTest8 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException{
Class<?> cls = Class.forName("com.jkx.lzh.test.Book");
Object obj = cls.newInstance();
Book b = (Book) obj;
System.out.println(b);
}
}
"*** Book的构造方法 ***
--- 这是Book方法 ---"
有了反射之后,以后进行对象化实例化的操作不在只是单独的依靠关键字new完成了,反射也同样可以,但是这并不表示new就被完全取代了。
这样有人就会说:“下面两行代码相当于:Book b = new Book();这样不是更复杂了,么“。
Class<?> cls = Class.forName(“com.jkx.lzh.test.Book”);
Object obj = cls.newInstance();
PS: 在任何的开发之中,new是造成耦合的最大元凶。一切的耦合都起源于new。
** 范例:**观察工厂模式-->
interface Fruit{
void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("* 吃苹果 *");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple" == className){
return new Apple();
}
return null;
}
}
public class TestFactory {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
"* 吃苹果 *"
代码如上,但是此时,如果我们要增加一个Fruit接口子类“orange”,就意味着我们就要修改工厂模式的方法。
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("* 吃橘子 *");
}
}
class Factory{
public static Fruit getInstance(String className){
if("apple" == className){
return new Apple();
}else if("orange" == className){
return new Orange();
}
return null;
}
}
由此可见,每增加一个Fruit接口子类,就要修改工厂类,那么如果随时需要增加子类呢?
因为现在工厂类都是new关键字直接实例化的,所以new就造成了所有问题的关键点。要想解决这一问题,就只能依靠反射完成。
修改工厂模式的方法如下:
package com.jkx.lzh.test;
interface Fruit{
void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("* 吃苹果 *");
}
}
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("* 吃橘子 *");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit f = null;
try {
f = (Fruit) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
public class TestFactory {
public static void main(String[] args) {
Fruit f = Factory.getInstance("com.jkx.lzh.test.Apple");
f.eat();
}
}
此时的程序就真正的完成了解耦合的目的,而且可扩展性非常强。
使用反射调用构造
--------
在之前所编写的代码中,我们都默认调用了类中的无参构造方法。可是类中也有可能不提供无参构造方法。
**范例:**观察当前程序的问题
Book.java
package com.jkx.lzh.po;
public class Book {
private String title;
private double price;
public Book(String title,double price){
this.title = title;
this.price = price;
}
public String toString(String title,double price) {
return "书名:"+ this.title + "价格: " + this.price ;
}
}
ReflectTest9.java
package com.jkx.lzh.test;
public class ReflectTest9 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException{
Class<?> cls = Class.forName("com.jkx.lzh.po.Book");
Object obj = cls.newInstance();
System.out.println(obj);
}
}
以上代码由于Book没有无参构造方法(<init>()),所以抛出以下异常:
Exception in thread “main” java.lang.InstantiationException: com.jkx.lzh.po.Book
at java.lang.Class.newInstance(Class.java:427)
at com.jkx.lzh.test.ReflectTest1.main(ReflectTest1.java:7)
Caused by: java.lang.NoSuchMethodException: com.jkx.lzh.po.Book.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 1 more
那么怎么解决这个问题呢?
在Class类中提供了这么一个构造方法可以取得构造:
1. 取得全部构造方法:public Constructor<?>\[\] getConstructors() throws SecurityException;
2. 取得一个指定参数顺序的构造:public Constructor<T>(**Class<?> ... ParameterTypes**) throws NoSuchMethodException,SecurityException;
以上两个方法返回都是“java.lang.reflect.Constructor”类的对象。在这个类中我们提供一个明确传递有参构造内容实例化对象方法:
public T **newInstance(Object... initargs)** throws InstantiationException,IllegalAccessException,IllegalAccessException,IllegalArgumentException,InvocationTargetException;
**范例:**明确调用类中的构造方法
ReflectTest9.java修改如下:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectTest9 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
SecurityException, IllegalArgumentException, InvocationTargetException{
Class<?> cls = Class.forName("com.jkx.lzh.po.Book");
//public Book(String title,double price);Constructor传的是有参构造的参数类型
Constructor<?> con = cls.getConstructor(String.class,double.class);
Object obj = con.newInstance("JAVA 反射,",82.22);
System.out.println(obj);
}
}
"书名:JAVA 反射价格: 82.22"
以上给我一个警示:在我们的简单java类的开发中不管提供多少构造方法,我们至少要保留无参构造方法。
反射调用方法
------
**类中普通方法只有在这个类实例化对象之后才能被调用。并且实例化方法有三种(new,conle,反射)**
**范例:**定义一个类
public class Book {
private String title;
public String getTitle() {
最后
面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典
想获取个人高清面试题的可以戳这里免费领取及个人也准备了很多面试题含答案的资料供你刷!
- Java核心知识整理
Java核心知识
- Spring全家桶(实战系列)
- 其他电子书资料
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
private String title;
public String getTitle() {
最后
面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典
想获取个人高清面试题的可以戳这里免费领取及个人也准备了很多面试题含答案的资料供你刷!
- Java核心知识整理
[外链图片转存中…(img-17n2MiZQ-1628234415923)]
Java核心知识
- Spring全家桶(实战系列)
[外链图片转存中…(img-Kw3dBnzH-1628234415926)]
- 其他电子书资料
[外链图片转存中…(img-0B4jGx3Q-1628234415927)]
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
[外链图片转存中…(img-cusREb4d-1628234415930)]