Java面向对象(六)
Java面向对象(六)
1.1反射
java的灵魂。
概念:在运行状态下,对于任何一个类,都能够知道类的属性和方法,对于任何一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息的行为叫做反射。(反射和封装的思想是相违背的)
public class Person {
public String name;
protected int age;
char gender;
private String email;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
", email='" + email + '\'' +
'}';
}
public void speak(String s){
System.out.println(s);
}
protected void speak(){
System.out.println("protected speak()");
}
void run(){
System.out.println("running");
}
private String eat(String s){
System.out.println("private method()");
return "eating " + s;
}
public void test1(){
System.out.println("test1");
}
public void test2(String s,int i){
System.out.println(s + i);
}
}
public class Student {
public Student(){
System.out.println("我是无参构造器...");
}
public Student(char name){
System.out.println("姓名 " + name);
}
public Student(String name){
System.out.println("姓名 " + name);
}
public Student(String name,int age){
System.out.println("姓名 " + name +" " + "年龄 " + age);
}
protected Student(boolean b){
System.out.println("protected " + b);
}
private Student(int age){
System.out.println(age);
}
}
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;
public class ReflectDemo implements Serializable,Cloneable{
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
//getPackage();
//getClassObject();
//getSuperClassAndInterfaceImpl();
//getConstructors();
//getAttributes();
//getMethods();
//getAnyMethod();
//genericCheck();
modifyArray();
}
/**
* 1.获取当前类的包名
*/
public static void getPackage(){
ReflectDemo reflectDemo = new ReflectDemo();
System.out.println(reflectDemo.getClass().getName());
}
/**
* 2. 获取Class的类对象
*/
public static void getClassObject(){
Class<?> c1 = null;
Class<?> c2 = null;
Class<?> c3 = null;
/**
* 第一种最常用
* 通过Class的静态方法forName()获取
*/
try {
c1 = Class.forName("com.oop.reflection.ReflectDemo");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/**
* 因为所有的类都继承自Object
* 所以Object的getClass()可以获取
*/
c2 = new ReflectDemo().getClass();
/**
* 任何数据类型(包括基本数据类型)都有一个静态的class属性
*/
c3 = ReflectDemo.class;
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
}
/**
* 3.获取父类和接口的实现
*/
public static void getSuperClassAndInterfaceImpl() throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.oop.reflection.ReflectDemo");
//取父类
Class<?> superClazz = clazz.getSuperclass();
System.out.println(superClazz.getName());
Class<?> [] interfaces = clazz.getInterfaces();
for (int i = 0; i < interfaces.length ; i++) {
System.out.println((i+1) + " " + interfaces[i].getName());
}
}
/**
* 4.获取类的构造方法
*/
public static void getConstructors() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//加载类对象
Class clazz = Class.forName("com.oop.reflection.Student");
System.out.println("-----------构造方法列表-------------");
//这种方式只能获取到公有的构造器
Constructor[] constructors = clazz.getConstructors();
for (Constructor c : constructors){
System.out.println(c);
}
Constructor constructor = clazz.getConstructor(null);
System.out.println(constructor);
//Student student = new Student();
//反射调用构造器
Object obj = constructor.newInstance();
System.out.println(obj);
//调用私有构造器
constructor = clazz.getDeclaredConstructor(int.class);
System.out.println(constructor);
constructor.setAccessible(true);
obj = constructor.newInstance(20);
System.out.println(obj);
System.out.println("------------------------------");
//获取所有构造器
constructors = clazz.getDeclaredConstructors();
for (Constructor c : constructors){
System.out.println(c);
}
}
/**
* 5.获取一个类中的所有属性
*/
public static void getAttributes() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName("com.oop.reflection.Person");
//获取类中的公有属性
Field[] fields = clazz.getFields();
for (Field field : fields){
System.out.println(field);
}
System.out.println("------获取所有属性-------");
fields = clazz.getDeclaredFields();
for (Field field : fields){
System.out.println(field);
}
System.out.println();
//调用公有的属性
Field f = clazz.getField("name");
System.out.println(f);
Object obj = clazz.getConstructor().newInstance();
f.set(obj,"YCL");
System.out.println(obj);
System.out.println("-----------------");
//私有属性
f = clazz.getDeclaredField("email");
System.out.println(f);
f.setAccessible(true);
f.set(obj,"ycl@a.com");
System.out.println(obj);
//TODO 把age,和gender属性赋值
}
/**
* 6.获取类中所有的方法
*/
public static void getMethods() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName("com.oop.reflection.Person");
//获取公有方法,包括父类
Method[] methods = clazz.getMethods();
for (Method m : methods){
System.out.println(m);
}
System.out.println();
//获取私有方法
methods = clazz.getDeclaredMethods();
for (Method m : methods){
System.out.println(m);
}
System.out.println();
//调用公有方法
Method m = clazz.getMethod("speak",String.class);
Object obj = clazz.getConstructor().newInstance();
m.invoke(obj,"Hello");
//调用私有方法
m = clazz.getDeclaredMethod("eat", String.class);
m.setAccessible(true);
Object res = m.invoke(obj,"Apple");
System.out.println(res);
}
/**
* 7.调用某个类的方法
*/
public static void getAnyMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class clazz = Class.forName("com.oop.reflection.Person");
Method method = clazz.getMethod("test1");
method.invoke(clazz.newInstance());
method = clazz.getMethod("test2", String.class, int.class);
method.invoke(clazz.newInstance(),"a",12);
}
/**
* 8.通过反射绕过检查泛型
*/
public static void genericCheck() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
//存一个非Integer的对象
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list,"反射检查泛型");
for (Object obj : list){
System.out.println(obj);
}
System.out.println(list.get(2));
}
/**
* 9,通过反射修改数组信息
*/
public static void modifyArray(){
int[] a = {1,2,3,4,5,6,7};
System.out.println(a.length);
int[] newA = (int[]) modifySize(a,10);
printArray(newA);
String[] strs = {"a","b","c"};
String[] newStrs = (String[]) modifySize(strs,5);
printArray(newStrs);
}
private static void printArray(Object obj) {
Class<?> c = obj.getClass();
if (!c.isArray()){
return;
}
Class<?> array = obj.getClass().getComponentType();
System.out.println("Array type:"+array.getName());
System.out.println("Array length:"+ Array.getLength(obj));
for (int i = 0; i < Array.getLength(obj) ; i++) {
System.out.print(Array.get(obj,i) + " ");
}
System.out.println();
}
private static Object modifySize(Object obj, int length) {
Class<?> array = obj.getClass().getComponentType();
Object newArray = Array.newInstance(array,length);
int l = Array.getLength(obj);
System.arraycopy(obj,0,newArray,0,l);
return newArray;
}
}
1.2反射和代理
public interface Subject {
String eating(String name,int num);
}
import com.oop.reflection.proxy.Subject;
public class RealSubject implements Subject {
@Override
public String eating(String name, int num) {
return "Eating with " + name + " and NO. is " + num;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyProxy implements InvocationHandler {
private Object obj = null;
public Object bind(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object action = method.invoke(this.obj,args);
return action;
}
}
import com.oop.reflection.proxy.impl.RealSubject;
public class TestProxy {
public static void main(String[] args) {
//代理
MyProxy proxy = new MyProxy();
//绑定代理对象
Subject subject = (Subject) proxy.bind(new RealSubject());
String res = subject.eating("Tom",1999);
System.out.println(res);
}
}
1.3反射和工厂
public class Factory {
public static Fruit getInstance(String className){
Fruit fruit = null;
try {
//通过反射构建工厂对象
fruit =(Fruit)Class.forName(className).newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
return fruit;
}
}
public interface Fruit {
void eat();
}
import com.oop.reflection.factory.Fruit;
public class Apple implements Fruit {
@Override
public void eat() {
System.out.println("Eating apple");
}
}
import com.oop.reflection.factory.Fruit;
public class Orange implements Fruit {
@Override
public void eat() {
System.out.println("Eating orange");
}
}
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class FactoryTest {
public static void main(String[] args) throws IOException {
String key="className";
Fruit fruit = Factory.getInstance(getValue(key));
if (fruit != null){
fruit.eat();
}
}
public static String getValue(String key) throws IOException {
//配置文件对象
Properties prop = new Properties();
//通过反射读取类路径下的文件
InputStream in =FactoryTest.class.getResourceAsStream("prop.txt");
prop.load(in);
return prop.getProperty(key);
}
}
/**prop.txt*/
className=com.oop.reflection.factory.impl.Orange
1.4 ClassLoader
/**
* 什么是ClassLoader
* 把类加载到JVM,bootstrap启动加载器,userDefineClassLoader用户自定义类加载器
* System ClassLoader ---> Extension ClassLoader ---> Bootstrap ClassLoader自底向下检查类是否加载
* 自顶向下尝试加载类
* System ClassLoader <--- Extension ClassLoader <--- Bootstrap ClassLoader
* Bootstrap ClassLoader
* JVM核心库的类装载,该类加载器无法直接获取
* Extension ClassLoader
* 负责jdk_home/lib/ext/目录下的jar或者-D java.ext.dirs指定目录下的jar包装载
* System ClassLoader
* 负责java -classpath或者-D java.class.path所指定目录下的jar包的装载
*/
public class ClassLoaderTest {
public static void main(String[] args) throws ClassNotFoundException {
getClassLoader();
}
public static void getClassLoader() throws ClassNotFoundException {
//获取系统类加载器
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
System.out.println("System ClassLoader:" + classLoader);
//获取系统类加载器的父类
classLoader = classLoader.getParent();
System.out.println("Extension ClassLoader:" + classLoader);
//获取不到
classLoader = classLoader.getParent();
System.out.println("Bootstrap ClassLoader:" + classLoader);
//获取当前类的ClassLoader
classLoader = Class.forName("com.oop.reflection.classloader.ClassLoaderTest").getClassLoader();
System.out.println("ClassLoaderTest:" + classLoader);
//获取Object的ClassLoader
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println("Object:" + classLoader);
}
}

浙公网安备 33010602011771号