代码规范
编码要求:
0:写代码:
1):明确需求,我要做什么!!!
2):整理思路,我要怎么一步一步去实现功能.
3):按照思路去编写代码.
4):功能写完,一定要测试.
5):总结,该功能是怎么做出来的,下一次遇到,我该怎么迅速的解决.
定义标识符:
不能是关键字,保留字.
数字不能作为开始.
起一个有意义的英文单词,如果是多个单词组成,使用驼峰表示法,以后的每一个单词首字母大写.
--------------------------------------
包名:全部使用小写字母组成.
package 公司域名倒写.项目模块名.组件名;
域名: 520it.com
package com._520it.pss.util;
平时上课:以知识点的名称来取代模块名.
类名: 使用名词,首字母大写.
如:Employee, EmployeeAdvanceSetting
不要使用Java中自带类的类名,比如:不能起名String,System.
XxxDemo:Xxx的演示程序,XxxTest:Xxx的测试程序,XxxMock:Xxx的模拟程序.
Xxx表示一个对象或者模块.
接口名:使用名称/副词.首字母大写.
一般的,有的公司习惯以I作为前缀.
如:IEmployeeDAO,IEmployeeService.
方法名:表示功能,使用动词,首字母小写.
比如:save,delete,login,saveEmployee.
变量名:表示状态,使用名词,首字母小写.
比如:username,email,password.
常量名:使用final修饰的变量. publicstatic final 修饰.
全部使用大写字母组成,多个单词之间使用下划线分割.
Integer: MAX_VALUE/MIN_VALUE.反射
Class类和Object有什么关系:
Object:表示一切对象.
Class: 表示一切类.
--------------------------------------------------------------
什么是反射:在运行时期,动态的去获取类中的成员信息(包,父类,接口,修饰符,类名,构造器,字段,方法等).
Eclipse中的outline(大纲视图),就是通过反射编写,目的:呈现出该类中所有的成员信息.
反射的API:
Class:描述一切的类.
Constructor:描述一切的构造器.
Method: 描述一切的方法.
------------------------------------------------
使用反射:创建对象,调用方法:
反射操作性能较低,---->Java中的框架都是基于反射编写.-->反射是框架的基石.Eclipse中的Outline就是反射的一种体现
Class类和Class实例
Class 类:用来表示所有的类(类,枚举,接口,注解),是所有类的类型.
Class实例:表示在JVM中运行的一份份字节码文件.
-------------------------------------------------------------
Class类可以表示所有类,那到底当前的Class类表示哪一个类呢,是表示String,还是ArrayList呢?
为了解决该问题,SUN公司给Class类提供了一个泛型,用来表示当前所表示的是哪一个类.
若当前描述String类: 此时Class<String> clz.
若当前描述ArrayList类: 此时Class<ArrayList> clz.
-------------------------------------------------------------
表示Class对象的三种方式:
1):类型.class; 表示一份字节码
2):对象.getClass(); 获取该对象的真实类型
3):使用Class.forName(StringclassName):根据类的全限定名来获取Class对象
-------------------------------------------------------------
同一个类在JVM中就只有一份字节码.
九大内置的Class实例和数组的Class实例
基本数据类型不是对象,也没有全限定名,那如何获取Class实例呢?
8大基本数据类型和void关键字都可以表示为Class的实例.
如: Class clz1 = int.class; Class clz2 = boolean.class;
问题: int和Integer是同一种数据类型吗?
在包装类中都有一个叫TYPE的常量,返回对应基本类型的Class对象.
表示数组的Class对象:
如果:多个数组具有相同的元素类型并且维数也相同,此时才共享同一份字节码.
和元素没有关系.
获取构造器
Class类描述了所有的类的成员(构造器,方法等)--->Class类具有获取某一个类的构造器的方法.
-----------------------------------------------------------------------------------------
步骤:
1):获取被操作的类的字节码对象.
2):获取构造器
-----------------------------------------------------------------------------------------
Class类获取构造器方法:
Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
publicConstructor<?>[] getConstructors():该方法只能获取当前Class所表示类的public修饰的构造器
publicConstructor<?>[] getDeclaredConstructors():获取当前Class所表示类的所有的构造器,和访问权限无关
publicConstructor<T> getConstructor(Class<?>... parameterTypes):获取当前Class所表示类中指定的一个public的构造器
参数:parameterTypes表示:构造器参数的Class类型
如:public User(String name)
Constructor c = clz.getConstructor(String.class);
publicConstructor<T> getDeclaredConstructor(Class<?>... parameterTypes):获取当前Class所表示类中指定的一个的构造器
package _02_constructor;
import java.lang.reflect.Constructor;
public class Constructor_Demo {
/**
* @param args
* @throws Exception
* @throws NoSuchMethodException
* @throws Exception
*/
public static void main(String[] args) throws Exception{
//Class clz = Person.class;
//Person p1 = new Person();
//clz = p1.getClass();
Class clz = Person.class;
Constructor c1 = clz.getConstructor();
System.out.println(c1);
c1 = clz.getConstructor(String.class);
System.out.println(c1);
c1 = clz.getDeclaredConstructor(String.class,int.class);
System.out.println(c1);
System.out.println("-------------------");
//这里只能获取public的构造方法
Constructor[] c2 = clz.getConstructors();
for (Constructor constructor : c2) {
System.out.println(constructor);
}
System.out.println("-------------------");
//这里可以获得全部的构造方法,跟访问修饰符无关
c2 = clz.getDeclaredConstructors();
for (Constructor constructor : c2) {
System.out.println(constructor);
}
System.out.println("-------------------");
}
}
class Person{
public Person(){
System.out.println("这是无参构造方法");
}
public Person(String name){
System.out.println(name);
}
private Person(String name,int age){
System.out.println(name+"---"+age);
}
}
调用构造器创建对象
步骤:
1):获取被操作的类的字节码对象.
2):获取构造器
3):调用构造器中创建对象的方法.
-------------------------------------------------------------
Constructor<T>类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
常用方法:
publicT newInstance(Object... initargs):如调用带参数的构造器,只能使用该方式.
参数:initargs:表示调用构造器的实际参数
返回:返回创建的实例,T表示Class所表示类的类型
如果:一个类中的构造器是外界可以直接访问,同时没有参数.,那么可以直接使用Class类中的newInstance方法创建对象.
public Object newInstance():相当于new 类名();
调用私有的构造器:
setAccessible(true)package _03_newinstance;
import java.lang.reflect.Constructor;
public class NewInstance_Demo {
/**
* @param args
* @throws Exception
* @throws NoSuchMethodException
*/
public static void main(String[] args) throws NoSuchMethodException, Exception {
Class clz = Person.class;
//无参的构造器创建对象
Constructor c1 = clz.getConstructor();
c1.newInstance();
System.out.println("-------------------");
//有参的公共构造器对象
c1=clz.getConstructor(String.class);
c1.newInstance("haha");
System.out.println("-------------------");
//创建私有的构造器对象
c1= clz.getDeclaredConstructor(String.class,int.class);
c1.setAccessible(true);
c1.newInstance("luffy",18);
System.out.println("-------------------");
//另外无参的公共的,就是可以直接访问的无参构造器可以这样访问
Person.class.newInstance();
}
}
class Person{
public Person(){
System.out.println("这是无参构造器");
}
public Person(String name){
System.out.println("hello "+name);
}
private Person(String name,int age){
System.out.println(name+"---"+age);
}
}
获取方法
操作步骤:
1):获取方法所在类的字节码对象.
2):获取方法
-----------------------------------------------------------------
Class类中常用方法:
public Method[]getMethods():获取包括自身和继承过来的所有的public方法
public Method[]getDeclaredMethods():获取自身所有的方法(不包括继承的,和访问权限无关
public MethodgetMethod(String methodName,
Class<?>...parameterTypes):表示调用指定的一个公共的方法(包括继承的)
参数:
methodName: 表示被调用方法的名字
parameterTypes:表示被调用方法的参数的Class类型如String.class
public MethodgetDeclaredMethod(String name,
Class<?>...parameterTypes):表示调用指定的一个本类中的方法(不包括继承的)
参数:
methodName: 表示被调用方法的名字
parameterTypes:表示被调用方法的参数的Class类型如String.class
package _04_getandnewmethod;
import java.lang.reflect.Method;
public class Demo1 {
/**
* @param args
* @throws Exception
* @throws NoSuchMethodException
*/
public static void main(String[] args) throws NoSuchMethodException, Exception {
Class clz = Person.class;
Method[] m1 = clz.getMethods();
for (Method m : m1) {
System.out.println(m);
}
System.out.println("-------------------");
Method m2 = clz.getMethod("sayHello", String.class);
System.out.println(m2);
System.out.println("-------------------");
Method m3 = clz.getDeclaredMethod("sayBye", String.class,int.class);
System.out.println(m3);
}
}
class Person{
Person(){
System.out.println("默认构造方法");
}
public void sayHello(String name){
System.out.println("hello "+name);
}
private void sayBye(String name,int age){
System.out.println(age+" OUT "+name);
}
}
使用反射调用方法
操作步骤:
1):获取方法所在类的字节码对象.
2):获取被调用的方法.
3):使用Method类中的invoke方法来调用.
--------------------------------------------------------------
如何使用反射调用一个方法:
在Method类中有方法:
public Objectinvoke(Object obj,Object... args):表示调用当前Method所表示的方法
参数:
obj: 表示被调用方法底层所属对象
Method m =clz.getMethod("sayHi",String.class);
args:表示调用方法是传递的实际参数
返回:
底层方法的返回结果
调用私有方法:
在调用私有方法之前:应该设置该方法为可访问的
又因为Method是AccessibleObject子类,所以Method中具有该方法.
m.setAccessible(true);
--------------------------------------------------------------
使用反射来调用静态方法和数组参数方法:
如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
对于数组类型的引用类型的参数,底层会自动解包,为了解决该问题,我们使用Object的一维数组把实际参数包装起来.
使用反射调用方法时:王道做法:
Method对象.invoke(底层对象,newObeject[ 实际参数 ]);
package _04_getandnewmethod;
import java.lang.reflect.Method;
import java.util.Arrays;
public class InvokeDemo1 {
/**
* @param args
* @throws Exception
* @throws NoSuchMethodException
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) throws NoSuchMethodException, Exception {
Class clz = Person2.class;
Object obj = clz.newInstance();
//调用public void method1(String name)
Method mm1 = clz.getMethod("method1", String.class);
mm1.invoke(obj, "wiii");
System.out.println("-------------------");
Method mm2 = clz.getDeclaredMethod("method2",String.class,int.class);
mm2.setAccessible(true);
mm2.invoke(obj,"xyz",23);
//静态方法的调用 invoke的时候使用的是null 然后是一个Object数组的一个包裹(这里可以有效的解决引用类型的问题)
Method mm3 = clz.getMethod("method3", int[].class);
//mm3.invoke(null, new int[]{1,2,3,45,5});
mm3.invoke(null, new Object[]{new int[]{1,2,3,4,5}});
}
}
class Person2{
Person2(){
}
public void method1(String name){
System.out.println("hello "+name);
}
private void method2(String name,int age){
System.out.println(name+"---"+age);
}
public static void method3(int...nums){
System.out.println(Arrays.toString(nums));
}
}
使用反射获取字段
1.找到字段所在类的字节码
2.获取字段
public Field[]getFields():获取当前Class所表示类中所有的public的字段,包括继承的字段.
public FieldgetField(String fieldName):获取当前Class所表示类中该fieldName名字的public字段,包括继承的字段.
public Field[] getDeclaredFields():获取当前Class所表示类中所有的字段,不包括继承的字段.
public Field[] getDeclaredField(Stringname):获取当前Class所表示类中该fieldName名字的字段,不包括继承的字段.
给某个类中的字段设置值和获取值:
1,找到被操作字段所在类的字节码
2,获取到该被操作的字段对象
3,设置值/获取值
Field类常用方法:
void setXX(Object obj, XX value):为基本类型字段设置值,XX表示基本数据类型
void set(Object obj, Object value):表示为引用类型字段设置值
参数:
obj: 表示字段底层所属对象,若该字段是static的,该值应该设为null
value: 表示将要设置的值
-------------------------------------------------------------------------------------
XX getXX(Object obj) :获取基本类型字段的值,XX表示基本数据类型
Object get(Object obj) :表示获取引用类型字段的值
参数:
obj: 表示字段底层所属对象,若该字段是static的,该值应该设为null
返回:返回该字段的值.
反射相关的其他API
Class类中:
int getModifiers():获得修饰符
String getName():返回类的全限定名
Package getPackage():获得该类的包
String getSimpleName():获得类的简单名字
Class getSuperclass():获得类的父类
boolean isArray():判断该Class实例是否是数组
boolean isEnum() :判断该Class实例是否是枚举
Constructor,Method的信息:
去查阅相应类的API即可.
单例模式
classpath文件
环境变量:
---------------------------------------------------
PATH:告诉电脑去哪里去找javac/java等工具.
CLASSPATH:告诉JVM从哪里去找字节码文件.
在Eclipse项目/工程下有一个叫:.classpath的文件.
加载资源路径
package properties;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class demo1 {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//method1(); 绝对路径获取文件
//method3(); 当前加载类的类路径 也就是是demo1.class的同一个路径
//下面的代码是classpath的根路径
String fileName = "db.properties";
Properties pro = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream in = loader.getResourceAsStream(fileName);
pro.load(in);
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println("用户名是:"+username+",密码是:"+password);
}
private static void method3() throws IOException {
String fileName = "db.properties";
Properties pro = new Properties();
InputStream in = demo1.class.getResourceAsStream(fileName);
pro.load(in);
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println("用户名是:"+username+",密码是:"+password);
}
private static void method1() throws FileNotFoundException, IOException {
String fileName = "/Users/luffy/Desktop/javase/day18/resources/db.properties";
Properties pro = new Properties();
InputStream in = new FileInputStream(fileName);
pro.load(in);
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println("用户名是:"+username+",密码是:"+password);
}
}