2017年4月24号 晴 空气质量:中度污染
内容:反射及相关,java设计六大原则(自学)
一、反射机制
在 程序运行期间,对于任何一个类,都能获得它的所有方法和属性!
对于任何一个对象,都能调用它的任意方法和属性!
这种动态获取类的信息 或者动态调用对象的方法或者属性的功能! ===》java 反射机制
二、反射Demo
老师代码:
1)学生实体类:
package cn.bdqn.bean;
//学生实体类
public class Student extends Person {
private String name; // 私有化的姓名
public String address; // 公共的地址
protected int age; // 受保护的年龄
char sex; // 默认权限的性别
static {
System.out.println("student类中静态代码块!01");
}
{
System.out.println("student类中普通代码块!02");
}
public Student() {
System.out.println("student类中无参构造03");
}
// 私有的方法
private String getWords(String name) {
return name + "====>大家辛苦了!";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
2)父类person类:
package cn.bdqn.bean;
//父类人类
public class Person {
}
3)反射测试类:
package cn.bdqn.bean;
//反射测试类
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class ReflectTest {
/**
* 对象名.getClass() === 类名.class
* 都是获取类的class 实例
*
* 所有类的实例 都是Class类的对象
*/
@Test
public void test01() {
Student stu = new Student();
System.out.println("stu对象所属类的父类" + stu.getClass().getSuperclass());
System.out.println("Student类的父类" + Student.class.getSuperclass());
}
@Test
public void test02() {
Integer a = 5;
System.out.println(a.getClass().getSuperclass());
Class<?>[] interfaces = Integer.class.getSuperclass().getInterfaces();
for (Class<?> class1 : interfaces) {
System.out.println(class1.getName());
}
}
// 三种方式获取指定类的完整限定名 (全类名==包名+类名)
@Test
public void test03() {
try {
// 01. 常用(推荐)
System.out.println(Class.forName("cn.bdqn.bean.Student").getName());//此时会把类加载到JVM中!!
System.out.println(Class.forName("cn.bdqn.bean.Student")
.getSimpleName()); // 简单类名
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void test04() {
// 02.
System.out.println(Student.class.getName()); // 类名点
}
@Test
public void test05() {
// 03.
System.out.println(new Student().getClass().getName()); // 对象点
}
// 获取包名
@Test
public void test06() {
try {
Class c = Class.forName("cn.bdqn.bean.Student");
System.out.println(c.getPackage().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取类的修饰符
@Test
public void test07() {
try {
Class c = Class.forName("cn.bdqn.bean.Student");
System.out.println("类的修饰符===》"
+ Modifier.toString(c.getModifiers()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取属性的相关信息
@Test
public void test08() {
try {
Class c = Class.forName("cn.bdqn.bean.Student");
// Field[] fields = c.getFields();// 获取public修饰的属性
Field[] fields = c.getDeclaredFields(); // 获取所有的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println("获取所有属性的名称");
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println("获取所有属性的修饰符");
for (Field field : fields) { // default的int 是0
System.out.println(Modifier.toString(field.getModifiers()));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 通过反射获取类中的构造方法
@Test
public void getConstructors() throws Exception {
Class c = Class.forName("cn.bdqn.test.Student"); // 加载静态代码块
Constructor[] constructors = c.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("构造的修饰符:"
+ Modifier.toString(constructors[i].getModifiers()));
System.out.println("构造的名称:" + constructors[i].getName());
/**
* 1.8才有getParameterCount
System.out
.println("构造的参数个数:" + constructors[i].getParameterCount());
*/
Class[] types = constructors[i].getParameterTypes(); // 参数的类型
for (Class class1 : types) {
System.out.println("参数类型的名称:" + class1.getName());
System.out.println("参数的类型简写:" + class1.getSimpleName());
}
System.out.println("******************************");
}
}
// 通过反射观察执行顺序
@Test
public void test09() {
// Student stu = new Student(); 耦合
try {
Class c = Class.forName("cn.bdqn.bean.Student");
Student student = (Student) c.newInstance(); // 解耦合
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
// 调用类的私有方法
@Test
public void test10() throws Exception {
Class c = Class.forName("cn.bdqn.bean.Student"); // 没有实例化对象
// 获取类中所有的方法
Method[] methods = c.getDeclaredMethods();
Method method = c.getDeclaredMethod("getWords", String.class);
// 实例化对象
Student stu = (Student) c.newInstance();
// 打开开关
method.setAccessible(true);
// 执行方法
String result = (String) method.invoke(stu, "小黑");
System.out.println(result);
}
}
三、传参中的一种模式(...)
老师代码:
1)参数...类
package cn.bdqn.bean;
//参数...类
public class ArrayPPP {
/**
* ...的注意事项:
* 01.底层就是一个数组,操作它就是操作我们的数组
* 02.在作为参数的时候,必须位于参数列表的最后一个位置
* 03.它可以是0-N个数据的组合
* 04.只能作为参数,并不能代替数组的声明
*/
public static void main(String[] args) {
int[] nums = { 1, 2, 3, 4, 5 };
changeNums(500);
System.out.println(nums[0]);
}
private static void changeNums(int num, int... nums) {
nums[0] = num;
}
/**
* private static void changeNums(int num, int [] nums) {
nums[0] = num;
}*/
}
2)测试类
package cn.bdqn.bean;
//测试类
public class PTest {
public static void main(String[] args) {
String[] words = test("a", "n", "c");
// 会把"a", "n", "c" 封装成一个String类的数组 传给 words
System.out.println(words[0]);
}
public static String[] test(String... words) {
words[0] = "5555";
for (String s : words) {
System.out.println(s);
}
return words;
}
}
四、java设计中的六大原则
转载自:http://blog.csdn.net/cq361106306/article/details/38708967
六种设计原则
(一)单一职责原则
(二)里氏替换原则
1.子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
2.子类中可以增加自己特有的方法。
3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
一句话总结:尽量不要重写父类的已经实现了的方法,可以用接口等其他方法绕过
(三)依赖倒置原则
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
这里用一个列子来说明:
- import java.util.LinkedList;
- import java.util.Queue;
- interface IEAT
- {
- public void eat();//抽象吃这个动作
- }
- class EatApple implements IEAT
- {
- @Override
- public void eat()
- {
- //这里是吃苹果
- System.out.print("eat a apple");
- }
- }
- class EatWater implements IEAT
- {
- @Override
- public void eat() {
- // 这里是吃水
- System.out.print("dringk water");
- }
- }
- public class Human
- {
- public void dosomething(IEAT ieat)//我爱吃东西,吃什么呢,看传入什么
- {
- ieat.eat();
- }
- /*
- public void dosomething(String food)//我爱吃东西,吃什么呢,看传入什么
- {
- if(food.equals("apple"))
- {
- //吃苹果
- }
- if(food.equals("water"))
- {
- //喝水
- }
- }
- */
- public static void main(String[] args)
- {
- Human human=new Human();
- /*
- human.dosomething("apple");
- human.dosomething("water");
- */
- //给你吃个苹果
- human.dosomething(new EatApple());
- //再给你喝点水
- human.dosomething(new EatWater());
- }
- }
其中注释的就是我们常用的方法。这种方法非常不适于扩展,因为如果要吃香蕉,吃西瓜,又要在dosomething里面写一堆判断。写着写着就混了。
因此一句话总结:多用抽象的接口来描述相同的动作,降低实现这个动作的人和物之间的耦合度
(四)接口隔离原则
(五)迪米特法则
迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
这个有点不好记,总结就是:father1<-child1,father2<-child2,father1和father2是的手下, father1尽量通过father2去访问child2, 不要直接在类里面访问child2. 下属怎么能随便去领导家的孩子呢,小心别人说你拐卖
(六)开闭原则
这个没啥好说的:尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
五、作业
1、总结U1的MindManager(周三上课前交ftp)
2、写soso,周五考试+答辩
3、周四晚上考linux和hadoop命令
六、老师辛苦了!