static是静态修饰符,一般修饰成员。被static修饰的成员属于类,不属于单个这个类的某个对象。static修饰的成员被多个对象共享。static修饰的成员属于类,但是会影响每一个对象。被static修饰的成员又叫类成员,不叫对象的成员。
被static修饰的成员变量属于类,不属于这个类的某个对象。
class Demo {
public static int num = 100;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.num = 200;
System.out.println(d1.num); //结果为200
System.out.println(d2.num); //结果为200
}
}
静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。
class Demo {
//成员变量
public int num = 100;
//静态方法
public static void method(){
//this.num; 不能使用this/super。
//System.out.println(this.num);//报错
}
}
同一个类中,静态成员只能访问静态成员
class Demo {
//成员变量
public int num = 100;
//静态成员变量
public static int count = 200;
//静态方法
public static void method(){
//System.out.println(num); 静态方法中,只能访问静态成员变量或静态成员方法
System.out.println(count);
}
}
被static修饰的成员可以并且建议通过类名直接访问。
类名.静态成员变量名
类名.静态成员方法名(参数)
对象名.静态成员变量名 // 不建议使用
对象名.静态成员方法名(参数) // 不建议使用
class Demo {
//静态成员变量
public static int num = 100;
//静态方法
public static void method(){
System.out.println("静态方法");
}
}
class Test {
public static void main(String[] args) {
System.out.println(Demo.num);
Demo.method();
}
}
静态代码块:定义在成员位置,使用static修饰的代码块{ }。
public class Person {
private String name;
private int age;
//静态代码块
static{
System.out.println("静态代码块执行了");
}
}
开发中,我们想在类中定义一个静态常量,通常使用public static final修饰的变量来完成定义。此时变量名用全部大写,多个单词使用下划线连接。
定义格式:
public static final 数据类型 变量名 = 值;
class Company {
//比如公司名称公司地址 可能会很长很长 我们记不住 每次使用还容易打错
//这时将其定义为静态常量 方便访问 还不容易出错
public static final String COMPANY_NAME = "我的公司";
}
当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。
System.out.println(Company.COMPANY_NAME);
注意:接口中的每个成员变量都默认使用public static final修饰。
所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
interface Inter {
public static final int COUNT = 100;
}
访问接口中的静态变量
Inter.COUNT
静态导入就是java包的静态导入,使用import static 静态导入包 , 这样可以直接使用方法名去调用静态的方法。
静态导入格式:
import static 包名.类名.方法名;
import static 包名.类名.*;
定义A类 如下, 含有两个静态方法 :
public class A {
public static void print(Object s){
System.out.println(s);
}
public static void print2(Object s){
System.out.println(s);
}
}
静态导入一个类的某个静态方法 , 使用static和类名A .方法名 , 表示导入A类中的指定方法 , 代码演示 :
import static com.paopao.A.print;
public class Demo {
public static void main(String[] args) {
print("test string");
}
}
如果有多个静态方法 , 使用static和类名A . * , 表示导入A类里的所有的静态方法, 代码演示 :
import static com.paopao.A.*;
public class Demo {
public static void main(String[] args) {
print("test string");
print2("test2 string");
}
}
在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
| public | protected | default(空的) | private | |
|---|---|---|---|---|
| 同一类中 | √ | √ | √ | √ |
| 同一包中(子类与无关类) | √ | √ | √ | |
| 不同包的子类 | √ | √ | ||
| 不同包中的无关类 | √ |
可见,public具有最大权限。private则是最小权限。
编写代码时,如果没有特殊的考虑,建议这样使用权限:
private ,隐藏细节。 public ,方便创建对象。public ,方便调用方法。不加权限修饰符,其访问能力与default修饰符相同
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
定义格式:
class 外部类 {
class 内部类{
}
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine 就可以使用内部类来描述,定义在成员位置。
代码举例:
class Car { //外部类
class Engine { //内部类
}
}
内部类可以直接访问外部类的成员,包括私有成员。
外部类要访问内部类的成员,必须要建立内部类的对象。
创建内部公共(public)类对象格式:
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
访问演示,代码如下:
定义类:
public class Person {
private boolean live = true;
class Heart {
public void jump() {
// 直接访问外部类成员
if (live) {
System.out.println("心脏在跳动");
} else {
System.out.println("心脏不跳了");
}
}
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
}
定义测试类:
public class InnerDemo {
public static void main(String[] args) {
// 创建外部类对象
Person p = new Person();
// 创建内部类对象
Person.Heart heart = p.new Heart();
// 调用内部类方法
heart.jump();
// 调用外部类方法
p.setLive(false);
// 调用内部类方法
heart.jump();
}
}
输出结果:
心脏在跳动
心脏不跳了
内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号
比如,Person$Heart.class
带具体实现的 父类或者父接口的 匿名的 子类对象。开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
new 父类名或者接口名(){
// 方法重写
@Override
public void method() {
// 执行语句
}
};
以接口为例,匿名内部类的使用,代码如下:
定义接口:
public abstract class FlyAble{
public abstract void fly();
}
匿名内部类可以通过多态的形式接受
public class InnerDemo01 {
public static void main(String[] args) {
/*
1.等号右边:定义并创建该接口的子类对象
2.等号左边:是多态,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飞了~~~");
}
};
}
}
匿名内部类直接调用方法
public class InnerDemo02 {
public static void main(String[] args) {
/*
1.等号右边:定义并创建该接口的子类对象
2.等号左边:是多态,接口类型引用指向子类对象
*/
new FlyAble(){
public void fly() {
System.out.println("我飞了~~~");
}
}.fly();
}
}
方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递
public class InnerDemo3 {
public static void main(String[] args) {
/*
1.等号右边:定义并创建该接口的子类对象
2.等号左边:是多态,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飞了~~~");
}
};
// 将f传递给showFly方法中
showFly(f);
}
public static void showFly(FlyAble f) {
f.fly();
}
}
以上可以简化,代码如下:
public class InnerDemo2 {
public static void main(String[] args) {
/*
创建匿名内部类,直接传递给showFly(FlyAble f)
*/
showFly( new FlyAble(){
public void fly() {
System.out.println("我飞了~~~");
}
});
}
public static void showFly(FlyAble f) {
f.fly();
}
}
类名作为方法的形参
方法的形参是类名,其实需要的是该类的对象
实际传递的是该对象的【地址值】
类名作为方法的返回值
方法的返回值是类名,其实返回的是该类的对象
实际传递的,也是该对象的【地址值】
示例代码:
public class Person{
public void eat(){
System.out.println("人吃了");
}
}
public class Test{
public static void main(String[] args){
method(new Person());
Person p = method2();
}
pubic static void method(Person p){
p.eat();
}
public static Person method2(){
return new Person();
}
}
抽象类作为形参和返回值
示例代码:
public abstract class Animal{
public abstract void eat();
}
public class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
public class Test{
public static void main(String[] args){
method(new Cat());
Animal a = method2();
}
public static void method(Animal a){
a.eat();
}
public static Animal method2(){
return new cat();
}
}
接口作为形参和返回值
示例代码:
public interface Fly{
public abstract void fly();
}
public class Bird implements Fly{
public void fly(){
System.out.println("我飞了");
}
}
public class Test{
public static void main(String[] args){
method(new Bird());
Fly f = method2();
}
public static void method(Fly f){
f.fly();
}
public static Fly method2(){
return new Bird();
}
}
公司类
属性
总资产属性
所有员工属性
方法
发工资方法:从总资产中减去所有员工支出。
员工:
属性
姓名
工号
存款
工资
经理、厨师、服务员均为员工子类。经理在员工基础上添加奖金属性。发完工资后,请查看所有员工的存款情况.
公司类加入调整员工工资方法:返回值为void
参数为:被调整工资的员工与调整金额(涨工资为正数、降工资为负数)。
方法体逻辑为,在员工工资的基础上调整相应的金额
在上边需求基础上,添加评选幸运员工(随机抽取一名员工并返回)。
// Employee.java
public class Employee {
String name;
String id;
private double deposit;
private double salary;
public Employee() {}
public Employee(String name, String id, double deposit, double salary) {
this.name = name;
this.id = id;
this.deposit = deposit;
this.salary = salary;
}
public double getDeposit() {
return deposit;
}
public void setDeposit(double deposit) {
this.deposit = deposit;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
// Manager.java
public class Manager extends Employee {
private double bonus;
public Manager() {
}
public Manager(String name, String id, double deposit, double salary, double bonus) {
super(name, id, deposit, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bouns) {
this.bonus = bouns;
}
}
// Cooker.java
public class Cooker extends Employee {
public Cooker() {
}
public Cooker(String name, String id, double deposit, double salary) {
super(name, id, deposit, salary);
}
}
// Waiter.java
public class Waiter extends Employee{
public Waiter() {
}
public Waiter(String name, String id, double deposit, double salary) {
super(name, id, deposit, salary);
}
}
// Company.java
import java.util.ArrayList;
import java.util.Random;
public class Company {
private double property;
private ArrayList<Employee> employeeArrayList;
public Company() {
}
public Company(double property, ArrayList<Employee> employeeArrayList) {
this.property = property;
this.employeeArrayList = employeeArrayList;
}
public double getProperty() {
return property;
}
public void setProperty(double property) {
this.property = property;
}
public ArrayList<Employee> getEmployeeArrayList() {
return employeeArrayList;
}
public void setEmployeeArrayList(ArrayList<Employee> employeeArrayList) {
this.employeeArrayList = employeeArrayList;
}
public Boolean existEmployee(){
if (employeeArrayList == null || employeeArrayList.size() == 0) {
return false;
}
return true;
}
public void printEmployeeInfo(Employee employee) {
System.out.println("工号: " + employee.id);
System.out.println("姓名: " + employee.name);
System.out.println("存款: " + employee.getDeposit());
System.out.println("工资: " + employee.getSalary());
if (employee instanceof Manager) {
System.out.println("奖金: " + ((Manager) employee).getBonus());
}
System.out.println("==============================");
}
public void showEmployeeInfo() {
ArrayList<Employee> employeeArrayList = getEmployeeArrayList();
if (!existEmployee()){
System.out.println("暂无员工");
return ;
}
for (int i = 0; i < employeeArrayList.size(); i++) {
Employee employee = employeeArrayList.get(i);
printEmployeeInfo(employee);
}
}
public void showEmployeeInfo(Employee employee){
printEmployeeInfo(employee);
}
public void payingSalaries() {
if (!existEmployee()){
System.out.println("暂无员工");
return ;
}
for (int i = 0; i < employeeArrayList.size(); i++) {
Employee employee = employeeArrayList.get(i);
property -= employee.getSalary();
employee.setDeposit(employee.getDeposit() + employee.getSalary());
if (employee instanceof Manager) {
property -= ((Manager) employee).getBonus();
employee.setDeposit(employee.getDeposit() + ((Manager) employee).getBonus());
}
}
}
public Employee randomEmployee() {
Random r = new Random();
return employeeArrayList.get(r.nextInt(employeeArrayList.size()));
}
public void chageSalary(Employee employee, double howMuch) {
employee.setSalary(employee.getSalary() + howMuch);
}
}
// Demo.java
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<Employee> employeeArrayList = new ArrayList<>();
employeeArrayList.add(new Manager("张三","001",10000,2000,3000));
employeeArrayList.add(new Cooker("李四","002",1000, 2000));
employeeArrayList.add(new Waiter("王五","003",2000,2000));
Company company = new Company(1000000, employeeArrayList);
company.showEmployeeInfo();
company.payingSalaries();
company.showEmployeeInfo();
Employee employee = company.randomEmployee();
company.showEmployeeInfo(employee);
company.chageSalary(employee, -200);
System.out.println(employee.getSalary());
}
}
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一