在正常的程序中,先有类,然后再有对象。
public final Class<?> getClass() ;
public class TestDemo {
public static void main(String [] args) {
Date date = new Date() ; // 产生对象
System.out.println(date.getClass());
// 因为所有类都是 Object的子类,而getClass是final型所以所有类都有getClass()方法
}
}
class java.util.Date
发现:调用getClass()方法输出的是类的完整名称,等于找到了对象出处: ——这就是“反”
Class<?> cls = date.getClass(); // 此代码将Class类进行了实例化;getClass()是class类的实例化方法
Class<?> cls = Date.class;
Class<?> cls = Class.forName(String ClassName) ;
当获得一个类时,使用关键字 new 进行类对象实例化操作;但是如果有了Class对象,那么就可以利用反射进行对象实例化操作。
public T newInstance();
class Book {
public Book() {
System.out.println("**********Book类 ***********");
}
@Override
public String toString() {
return "Hello,World!";
}
}
public class TestDemo {
public static void main(String [] args) throws InstantiationException, ReflectiveOperationException {
Class<?> cls = Class.forName("helloworld.Book");
@SuppressWarnings("deprecation")
Object obj = cls.newInstance();
Book book = (Book) obj ;// 向下转型
System.out.println(book);// 调用了Book类的对象
// 此过程没有 new 关键字实例化Book类,而是通过反射来实例化对象
}
}
在反射机制的加持下,类的对象实例化则不再单独依靠 new关键字 。
package helloworld;
interface Fruit { // 函数是接口
public void eat() ;
}
class Apple implements Fruit {
@Override
public void eat() {
System.out.println("苹果");
}
}
class Factory {
public static Fruit getInstance(String className) {
if ("apple".equals(className)) {
return new Apple();
}
return null ;
}
}
public class TestFactory {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple");// 实例化Fruit对象
f.eat();
}
}
package helloworld;
interface Fruit { // 函数是接口
public 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) {
if ("apple".equals(className)) {
return new Apple();
} else if ("orange".equals(className)) {
return new Orange();
} else {
return null ;
}
}
}
public class TestFactory {
public static void main(String[] args) {
Fruit f = Factory.getInstance("apple");// 实例化Fruit对象
f.eat();
}
}
package helloworld;
interface Fruit { // 函数是接口
public 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 {// 工厂类
@SuppressWarnings("deprecation")
public static Fruit getInstance(String className) throws InstantiationException, ReflectiveOperationException, ClassNotFoundException {
Fruit f = null ;
try {
f = ((Fruit) Class.forName(className).newInstance());
// 因为 Class.forName()方法返回的是Object(默认/推荐),所以需要向下转型为Fruit
} catch (Exception e) { }
return f ;
}
}
public class TestFactory {
public static void main(String[] args) throws InstantiationException, ClassNotFoundException, ReflectiveOperationException {
Fruit f = Factory.getInstance("helloworld.Apple");
f.eat();
}
}
// 程序中出现疑虑,可以参照"实例分析"
package helloworld;
public class Book {
private String title ;
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
}
类中有 无参构造方法 所以实例化对象的时候可以直接利用Class类中的newInstance()方法
public Method [] getMethods();
public Method getMethod(String className , Class<?>... parameterTypes);
public Object invoke(Object obj , Object … args);
package helloworld;
import java.lang.reflect.Method;
public class TestDemo {
public static void main(String [] args) throws InstantiationException, ReflectiveOperationException {
String classname = "title" ;
Class<?> cls = Class.forName("helloworld.Book");
Object obj = cls.newInstance(); // 给出了Book类的实例化对象
Method setMet = cls.getMethod("set" + initcap(classname),String.class);
Method getMed = cls.getMethod("get" + initcap(classname));
setMet.invoke(obj, "Java");
System.out.println(getMed.invoke(obj));
}
private static String initcap(String str) { // 首字母大写
return str.substring(0,1).toUpperCase() + str.substring(1) ;
}
}
public Field [] getDeclaredFields() ;
public Field getDeclaredFields() ;
public Object get(Object obj);
public void set(Object obj , Object Value);
package helloworld;
public class Book {
public String title ;
}
package helloworld;
import java.lang.reflect.Field;;
public class TestDemo {
public static void main(String [] args) throws InstantiationException, ReflectiveOperationException {
String classname = "title" ;
Class<?> cls = Class.forName("helloworld.Book");
Object obj = cls.newInstance(); // 给出了Book类的实例化对象
java.lang.reflect.Field titleField = cls.getDeclaredField("title") ;
titleField.set(obj, "Java");
System.out.println(titleField.get(obj));
}
}
package helloworld;
import java.lang.reflect.Field;;
public class TestDemo {
public static void main(String [] args) throws InstantiationException, ReflectiveOperationException {
String classname = "title" ;
Class<?> cls = Class.forName("helloworld.Book");
Object obj = cls.newInstance(); // 给出了Book类的实例化对象
Field titleField = cls.getDeclaredField("title") ;
titleField.setAccessible(true);// 取消封装
titleField.set(obj, "Java");
System.out.println( titleField.get(obj) );
}
}
构造方法和普通方法,也同样可以取消封装,但很少使用。