static (目标是静态的)
-
Static 变量不能在办法体中界说,因为,办法体中的变量为局部变量,局部变量存储在动态存储区
-
静态变量存储在静态存储区,能够认为规则静态变量不能界说在办法体内部。
-
Static办法中不能运用this和super关键字
-
不能调用非static办法,只能拜访所属类的静态成员变量和成员办法 因为当static办法被调用的时分这个类的目标可能还没有被创立,即使已经被创立了,也无法确定调用那个目标的办法,
-
static办法也不能拜访非static类型的变量。
final (常量:目标只能一次赋值操作)
示例
public class DefaultResourceLoader implements ResourceLoader {
//加载资源的类加载器
@Nullable
private ClassLoader classLoader;
# 用于存储注册的协议解析器
private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet(4);
# 缓存已加载的资源
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap(4);
static 、 final (静态常量:一同运用: 目标为静态且不能修正)
static final 一般界说 一个常数或许字符串反反复复运用时,内存就不会重复申请和释放
示例
(static) 办法是一个很重要的用处是完成单例模式。为了完成这一功能,有必要隐藏结构函数,因为结构函数被声明为private,外界无法直接创立这个类型的目标,只能经过该类供给的办法来获取类的目标。要到达这样的意图只能把创立目标的办法上名为static.
private final static SingleTon instance=new SingleTon();
/**
* 活动秘钥信息 accessKey为key
*/
public final static Map<String,ShopAccessInfo> SHOP_RSA_MAP = new HashMap<>();
@Component
@ConfigurationProperties(prefix = "prop")
@PropertySource(value = "config/rsa.properties")
public class CustomSecretKeyMap {
/**
* 对接秘钥信息
*/
private List<ShopAccessInfo> shops;
/**
* 获取秘钥信息
* @return
*/
public List<ShopAccessInfo> getShops() {
return shops;
}
/**
* 转换秘钥信息
* @param shops
*/
public void setShops(List<ShopAccessInfo> shops) {
if(CollectionUtils.isEmpty(shops)){
return;
}
this.shops = shops;
for(ShopAccessInfo shop:shops){
ActivityMapUtils.SHOP_RSA_MAP.put(shop.getAccessKey(),shop);
}
}
}
abstract
在笼统类,笼统办法本质上是界说接口规范,即规则高层类的接口,从而确保一切子类都有相同的接口完成,这样,多态就能发挥出威力。
- abstract常常用于润饰类或办法。
- **写了笼统办法,那么该类前面就要写abstract润饰。
- 父类是笼统类,子类承继该abstract类时,要么子类也是笼统类,也便是abstract润饰该类; 要么便是重写父类(abstract)的笼统办法。,假如父类没有笼统办法,则不用重写!!!
- abstract润饰办法便是为了子类重写该办法,笼统办法不能界说为private
- 笼统类不能创立目标
- 笼统类是不能被实例化的
实例化实际便是在内存中开辟一块空间用于存储新的产品,即目标。
在笼统类中,子类实例化会先初始化父类,但父类初始化并不是创立一个父类目标,而是把父类中界说的目标相关特点都初始化,因为这些特点子类目标也是具有的。
所以,为了确保子类目标的完好性,要从最底层的父类开始,逐级初始化,一切初始化都完成后才会发生一个完好的子类目标
- 初始化一个目标,创立一个目标需求调用该类的结构办法,而结构办法的意义便是给变量初始化
- 实例化一个目标,java会在内存中生成你new出来的那个类的实例,即目标。然后能够调用这个目标的办法进行操作,获取目标的公共成员等。
- java实例化有4种办法: 一、用new语句创立目标,这是最常用的创立目标办法。 二、运用反射手段,调用## java.lang.Class.newInstance() 或许java.lang.reflect.Constructor类的newInstance实例化办法。 例如: XML装备文件中,获取详细子类的类称号字符串subCLassName,然后根据取得类名字符串进行实例化。
Class c = Class.foName(subClassName);
User user = (User) c.newInstance(); //不带有任何参数
public Object getNewObject(String className) trows Exception {
Class tClass = Class.forName(className);
Object tObject = tClass.newInstance();
return tObject;
}
Class c = Class.foName(subClassName);
Constructor con = c.getConstructor(String.class);
User user = (User) con.newInstance("name");
三、调用目标的clone办法。
User user1 = new User(1, "mac");
User user2 = null;
user2 = (User) user1.clone();
四、运用反序列化机制。 序列化:把目标状况转化为可坚持或许传输的格式进程,被序列化的目标有必要implments Serializable; 反序列化:把流转换为目标的进程。 远程传输进程中 , 发送各种类型的数据,无论是哪种数据类型,都以二进制序列的方式在网络上传送,发送方需求把这个java目标转换为字节序列,才能够在网络上传送,也便是序列化的进程。
import org.junit.Test;
public class SerializableTest {
@Test
public void test() throws IOException {
Person zizhen = new Person ();
zizhen.age = 31;
zizhen.s = "自珍";
//obj 写入文件
FileOutputStream fileOutputStream = new FileOutputStream("temp"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(a);
fileOutputStream.close();
//经过文件读取obj
FileInputStream fileInputStream = new FileInputStream("temp");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Person zizhenClone = (A) objectInputStream.readObject();
fileInputStream.close();
System.out.println(zizhenClone.age);
System.out.println(zizhenClone.name);
}
}
public class Person implements Serializable {
int age;
String name;
}
//笼统类是不能被实例化的
AbstractApplicationContext abstractApplicationContext =new AbstractApplicationContext() {
@Override
protected void refreshBeanFactory() throws BeansException, IllegalStateException {
}
@Override
protected void closeBeanFactory() {
}
@Override
public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException {
return null;
}
};
//接口无法被实例化,可是能够被完成。
DefaultResourceLoader defaultResourceLoader =new DefaultResourceLoader();
- 静态办法是不允许被重写。
- 假如一个笼统类没有字段,一切办法悉数都是[笼统办法]就能够把该笼统类改写为接口(interface)。
// 笼统类Person
publice abstract class Person {
public abstract void work();
public abstract void life();
public abstract void eat();
/**
* Subclasses must implement this method to release their all pressure
* This method gets invoked by {@link #sleep()} after all other activities,etc: work, life , eat.
* <p>Should never throw an exception but rather log shut down the brain failures.
*/
public abstract void sleep();
}
}
将笼统类改写成接口
publice interface Person {
void run();
void eat();
}
- 接口(interface)便是比笼统类还要笼统的纯笼统接口,因为它连字段都不能有。
- 接口界说的一切办法默许都是public abstract的,所以这两个润饰符不需求写出来,写不写作用都相同。
- 接口无法被实例化,可是能够被完成。一个完成接口的类,有必要完成接口内所描绘的一切办法,不然就有必要声明笼统类。
- 接口的一切办法都是笼统办法,接口不能界说实例字段。
- Java中,一个类只能承继自另一个类,不能从多个类承继。而一个类能够完成多个接口。
代码示例
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
* Name of the MessageSource bean in the factory.
* If none is supplied, message resolution is delegated to the parent.
* @see MessageSource
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
/**
* Subclasses must return their internal bean factory here. They should implement the
* lookup efficiently, so that it can be called repeatedly without a performance penalty.
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
* @return this application context's internal bean factory (never {@code null})
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
* closed already
* @see #refreshBeanFactory()
* @see #closeBeanFactory()
*/
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
abstract static 不能 组合起来润饰办法
- abstract润饰的办法无办法体,不能随着类的加载而加载到办法区
- static润饰的办法随着类的加载会被加载到类的办法区;
- abstract还不能与final一起存在,因为final润饰的办法是最终办法,无法被重写,abstract 里边的笼统办法 意图是被派生类重写;
- abstract不能与private一起存在,因为private润饰的办法不行见,无法重写;
interface
- 假如一个笼统类没有字段,一切办法悉数都是[笼统办法]就能够把该笼统类改写为接口(interface)。
- 接口(interface)便是比笼统类还要笼统的纯笼统接口,因为它连字段都不能有。
/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from beans <i>created</i> by the FactoryBean. (用于撤销引证{@link FactoryBean}实例,差异 FactoryBean 创立的Bean)
For example, if the bean named
{@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} will return the factory, not the instance returned by the factory.(假如名为{@code myJndiObject}是一个FactoryBean,正在获{@code&myJndiObject}将回来工厂,而不是工厂回来的实例)
*/
public interface BeanFactory {
//常量:假如咱们在获取Bean的时分,运用&则获取的是FactoryBean自身目标,不然是获取getObject的署理目标。
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String var1) throws BeansException;
...
}
- 接口界说的一切办法默许都是public abstract的,所以这两个润饰符不需求写出来,写不写作用都相同。
- 接口无法被实例化,可是能够被完成。一个完成接口的类,有必要完成接口内所描绘的一切办法,不然就有必要声明笼统类。
- 接口的一切办法都是笼统办法,接口不能界说实例字段。
- Java中,一个类只能承继自另一个类,不能从多个类承继。而一个类能够完成多个接口。
// 笼统类Person
publice abstract class Person {
public abstract void work();
public abstract void life();
public abstract void eat();
/**
* Subclasses must implement this method to release their all pressure
* This method gets invoked by {@link #sleep()} after all other activities,etc: work, life , eat.
* <p>Should never throw an exception but rather log shut down the brain failures.
*/
public abstract void sleep();
}
将笼统类改写成接口
publice interface Person {
void run();
void eat();
}
interface default办法
完成类能够不用覆写default办法。
- default办法的意图是,当需求给接口新增一个办法时,会涉及到修正悉数子类。
- 假如新增的是default办法,那么子类就不用悉数修正,只需求在需求覆写的地方才去覆写新增办法。
- default办法和笼统类的一般办法是有所不同的,因为interface没有字段,default办法无法拜访字段,而笼统类的一般办法能够拜访实例字段。
代码示例
interface Person {
void eat();
String sleep();
}
// 将sleep()办法改为default办法
interface Person {
String eat();
default void sleep() {
System.out.println( "默许睡觉时间 0:00- 8:00 run");
}
}
Java8新特性界说一个扩展办法:
public interface Formula {
double calculate(int a);
default double sqrt(int a){
return Math.sqrt(a);
}
}
public class Bootstrap {
public static void main(String[] args){
Formula formula = new Formula(){
public double calculate(int a){
return sqrt(a * 100);
}
// 本来应该完成的sqrt办法因为新特性的呈现,变得不再那么冗余了
};
System.out.println(formula.calculate(100));
System.out.println(formula.sqrt(16));
}
}
经过该特性,咱们将能够很方便的完成接口默许完成类。这个特性在编译器完成的角度来说更接近于Scala的trait。
interface 接口的承继
一个interface能够承继另一个interface,interface承继自interface运用extends,它相当于扩展了接口的办法。
代码示例:
/**
* SPI interface to be implemented by most if not all application contexts.(SPI接口将由大多数(假如不是一切)应用程序上下文完成。)
* Provides facilities to configure an application context in addition(此外,还供给装备应用程序上下文的工具)
* to the application context client methods in the
* {@link org.springframework.context.ApplicationContext} interface.
*(承继 ApplicationContext接口中的应用程序上下文客户端办法)
* <p>Configuration and lifecycle methods are encapsulated here to avoid
* making them obvious to ApplicationContext client code. The present
* methods should only be used by startup and shutdown code.
*
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @since 03.11.2003
*/
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle {
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
String ENVIRONMENT_BEAN_NAME = "environment";
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
void setId(String var1);
void setParent(ApplicationContext var1);
ConfigurableEnvironment getEnvironment();
void setEnvironment(ConfigurableEnvironment var1);
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor var1);
void addApplicationListener(ApplicationListener<?> var1);
void refresh() throws BeansException, IllegalStateException;
void registerShutdownHook();
void close();
boolean isActive();
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
笼统类和接口差异
Java的接口特指interface的界说,表明一个接口类型和一组办法签名。而编程接口泛指接口规范,如:办法签名,数据格式,网络接口等
笼统类和接口差异: 笼统类(abstract class): 承继:只能extends一个class 字段:能够界说实例字段 笼统办法:能够界说笼统办法 非笼统办法:能够界说非笼统办法 接口(interface): 承继:能够extends多个interface& 能够implements多个interface 字段:不能界说实例字段 笼统办法:能够界说笼统办法 非笼统办法:能够界说default办法
1、面向目标特性:重载重写、承继、多态、反射
2、常见关键字 final、static、abstract、finalize、transient、native
3、StringBuffer、StringBuilder 和 String、字符常量池
4、六大设计原则、常见的设计模式(署理、工厂、单例、装修者、观察者)
5、反常、常见的反常类
6、序列化
7、深拷贝和浅拷贝、值传递和引证传递
8、笼统类和接口
9、根本类型的默许值和取值规模以及字节数
字段 field、 结构器 constructor、 特点(properties)(类特点、实例特点)、变量 (variable)、办法(method)、内部类(inner class) 有什么差异?
特点 :润饰符 数据类型 (特点类型)特点名 = 初始化值 ;
- Java中的特点(property),一般能够理解为get、set办法、is办法。
- 特点完成了字段的封装,特点有get、set 办法来操控字段,供外部拜访
Java中的特点,其实是相对于JavaBean来说的。所以在Java中,正确的说法应该是JavaBean中有XXX特点,Java类中有OOO字段或成员变量。特点的英文翻译是property
BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
System.out.println(propertyDescriptor.getName());
}
如上代码就会输出UserInfo类对应的JavaBean的一切特点名
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
//常量
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
//字段
private String id;
private String displayName;
private ApplicationContext parent;
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors;
private long startupDate;
private boolean active;
private boolean closed;
private final Object activeMonitor;
private final Object startupShutdownMonitor;
private Thread shutdownHook;
private ResourcePatternResolver resourcePatternResolver;
private LifecycleProcessor lifecycleProcessor;
private MessageSource messageSource;
private ApplicationEventMulticaster applicationEventMulticaster;
private Set<ApplicationListener<?>> applicationListeners;
private ConfigurableEnvironment environment;
//特点 对应的办法
public void setId(String id) {
this.id = id;
}
//特点 对应的办法
public String getId() {
return this.id;
}
//特点 对应的办法
public void setDisplayName(String displayName) {
Assert.hasLength(displayName, "Display name must not be empty");
this.displayName = displayName;
}
//特点 对应的办法
public String getDisplayName() {
return this.displayName;
}
//特点 对应的办法
public boolean isRunning() {
return this.getLifecycleProcessor().isRunning();
}
//特点 对应的办法
@Override
public String getApplicationName() {
return "";
}
//特点 对应的办法
/**
* Return the list of statically specified ApplicationListeners.(回来静态指定的applicationlistener的列表。)
*/
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
//办法
public void start() {
this.getLifecycleProcessor().start();
this.publishEvent(new ContextStartedEvent(this));
}
//办法
public void stop() {
this.getLifecycleProcessor().stop();
this.publishEvent(new ContextStoppedEvent(this));
}
字段
- 字段(field),一般叫做“类成员”,或 “类成员变量”,有时也叫“域”,理解为“数据成员”,用来承载数据的。
- Java中字段的意义便是Java类中界说的成员变量,能够经过Java的反射机制获取一切的字段名,
Class#getFields()
办法或许Class#getDeclaredFields()
办法,看出field其实便是字段的意思。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
//////常量const
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected final Log logger;
///////字段 field
private String id;
private String displayName;
private ApplicationContext parent;
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors;
private long startupDate;
private boolean active;
private boolean closed;
private final Object activeMonitor;
private final Object startupShutdownMonitor;
private Thread shutdownHook;
private ResourcePatternResolver resourcePatternResolver;
private LifecycleProcessor lifecycleProcessor;
private MessageSource messageSource;
private ApplicationEventMulticaster applicationEventMulticaster;
private Set<ApplicationListener<?>> applicationListeners;
private ConfigurableEnvironment environment;
办法 (method,函数)
变量 (接口里边为常量)
- 在办法体外,类体内声明的变量称为成员变量。
- 在办法体内部声明的变量称为局部变量。
特点和字段差异:
Java中的特点(property),一般能够理解为get和set办法。更形象的说便是:特点是对字段的封装,供外部拜访。 而字段(field),一般叫做“类成员”,或 “类成员变量”,有时也叫“域”,理解为“数据成员”,用来承载数据的。
JavaBean的特点名其实便是Java类中界说的setter或许getter办法名,去掉set或许get或许is得到的字符串,判断首字母是否是小写,如是,则该字符串便是特点名,不然再判断第二个字母是否是大写,如是,则该字符串便是特点名,不然将首字母小写得到的称号便是特点名,比如getDizhi()
办法特点名便是dizhi
,getdizhi()
办法特点名也是dizhi
,getdIzhi()
办法特点名便是dIzhi
,getDIzhi()
办法特点名便是DIzhi
,其间bool类型的特点的get办法名不是以get最初,而是以is最初。
对于只要get或许只要set办法的特点,咱们就说他是只读或只写特点。之所以规则Java的字段界说禁绝以is最初且首两个字母要么都大写要么都小写,便是为了让JavaBean的特点名与字段名一致。