I recently came across this question and have not been able to find a solution to it. I hope I will get a convincing answer here.
Question : Let A be a non abstract class which is extended (separately) by two classes B and C. Now the task is to allow only one instance of the these classes to be created. If the client code tries to create a second instance of any of these classes, then an exception should be thrown.
A obj11 = new A(); // Fine.
A obj12 = new A(); // thrown an exception.
B obj21 = new B(); // OR
A obj21 = new B(); // both these should be fine
But shouldn't allow 2nd instance of class B to be created.
Thanks in advance.
P.S. : This is different from singleton.
The following should do it. In the real world there should be some synchronized keywords. All crammed into one file for simplicity.
public class A {
static HashSet<Class> thereCanBeOnlyOne = new HashSet();
public A() {
Class c = this.getClass();
if (thereCanBeOnlyOne.contains(c))
throw new RuntimeException();
thereCanBeOnlyOne.add(c);
}
static public class B extends A {}
static public class C extends A {}
public static void main(String[] args) {
A a1 = new A();
B b1 = new B(); // OK
C c1 = new C(); // OK
C c2 = new C(); // throws exception
}
}
Is this ok for you?
public class A {
private static created = false;
public static A create() {
if (created) {
throws new RuntimeException();
} else {
created = true;
return new A();
}
}
protected A() {
}
}
public class B extends A {
private static created = false;
public static B create() {
if (created) {
throws new RuntimeException();
} else {
created = true;
return new B();
}
}
protected B() {
}
}
public class C extends A {
private static created = false;
public static C create() {
if (created) {
throws new RuntimeException();
} else {
created = true;
return new C();
}
}
protected C() {
}
}
You can create A, B, and C using:
A a = A.create();
B b = B.create();
C c = C.create();
I am a newbie to Java (I come from the C/C++ background) and I was having a hard time figuring out how to allocated memory of a data member in one class from another. For eg,
Class A
{
B bInA;
C cInA;
public void foo(someValue)
{
cInA = new C();
cInA.foo(bInA, someValue)
}
public static void main(String args[])
{
A myA = new A();
myA.foo(xyz)
// myA.bInA.value should be equal to xyz
}
}
Class B { ... }
Class C
{
public void foo(bInA, someValue)
{
bInA = new B();
bInA.value = someValue;
}
}
Can I do something like this in java?
Any help will be much appreciated.
----EDIT-----
Class A
{
B bInA;
C cInA;
public void foo(someValue)
{
cInA = new C();
bInA = new B();
cInA.foo(bInA, someValue)
}
public static void main(String args[])
{
A myA = new A();
myA.foo(xyz)
// myA.bInA.value should be equal to xyz
}
}
Class B { ... }
Class C
{
public void foo(bInA, someValue)
{
bInA.value = someValue;
}
}
Unless I'm misunderstanding your intention (change value of bInA from C), your recent edit seems to work fine. Here's my java version of your pseudocode.
class A
{
B bInA;
C cInA;
public void foo(int someValue)
{
cInA = new C();
bInA = new B();
cInA.foo(bInA, someValue);
System.out.println(bInA.value);
}
public static void main(String args[])
{
A myA = new A();
myA.foo(123);
// myA.bInA.value should be equal to xyz
}
}
class B { int value; }
class C
{
public void foo(B bInA, int someValue)
{
bInA.value = someValue;
}
}
Output
123
Java does not have pass-by-reference; rather, all you ever have are references to objects, and those references must be passed by value. So your code is roughly equivalent to something like this in C++:
class A {
private:
B *bInA = NULL;
C *cInA = NULL;
public:
void foo(someValue) {
cInA->foo(bInA, someValue);
}
static void main() {
A *myA = new A();
myA->foo(xyz)
// myA->bInA->value should be equal to xyz
}
}
int main() {
A::main();
return 0;
}
class B { ... }
class C {
public:
void foo(bInA, someValue) {
bInA = new B(); // defeats the point of having passed in a bInA
bInA->value = someValue;
}
}
(Except that the C++ code has memory leaks, since you allocate some things without freeing them, whereas in Java that's not an issue.)
I need to be able to create an instance of the following class in my web Services Method and for some reason there is an error.
Question: Why would I not be able to declare and instance of my class in my Java WEBServices?
**GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);**
Error:
The source was saved, but was not compiled due to the following errors:
C:\SoftwareAG\IntegrationServer\packages\DssAccessBackup\code\source\DssAccessBackup\services\flow.java:48: non-static variable this cannot be referenced from a static context
GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);
1 error
Code:
public final class ReturnListOfValidFileNames_SVC
{
/**
* The primary method for the Java service
*
* #param pipeline
* The IData pipeline
* #throws ServiceException
*/
public static final void ReturnListOfValidFileNames(IData pipeline)
throws ServiceException {
IDataCursor pipelineCursor = pipeline.getCursor();
String fileName = IDataUtil.getString(pipelineCursor,"FileName");
ArrayList<String> listOfFileName = new ArrayList<String>();
//This will get the file list and set it to the local parameter for the Service
**GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);**
listOfFileName = FindArrayListOfFiles.getMyFileList();
IDataUtil.put( pipelineCursor,"ListOfFileNames",listOfFileName.toArray());
pipelineCursor.destroy();
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
public class GetTheFileListClass {
String fileName = new String();
ArrayList<String> MyFileList = new ArrayList<String>();
String InputFile = new String();
GetTheFileListClass(String workFile){
setInputFile(workFile);
}
public void setMyFileList(ArrayList<String> myList, String newFileValueToAdd) {
myList.add(newFileValueToAdd);
}
public ArrayList<String> getMyFileList() {
return MyFileList;
}
public void setInputFile(String wFile) {
fileName = wFile;
}
public String getInputFile(){
return fileName;
}
private String returnFileName(String a) {
String matchEqualSign = "=";
String returnFile = new String();
int index = 0;
index = a.indexOf(matchEqualSign,index);
index++;
while (a.charAt(index) != ' ' && a.charAt(index) != -1) {
returnFile += a.charAt(index);
//System.out.println(returnFile);
index++;
}
return returnFile;
}
private void locatedFileName(String s, String FoundFile, ArrayList<String> myFileListParm) {
final String REGEX = ("(?i)\\./\\s+ADD\\s+NAME\\s*=");
Pattern validStringPattern = Pattern.compile(REGEX);
Matcher validRegMatch = validStringPattern.matcher(s);
boolean wasValidRegMatched = validRegMatch.find();
if (wasValidRegMatched) {
FoundFile = returnFileName(s); //OUTPUT variable should go here
setMyFileList(myFileListParm,FoundFile);
}
}
//This is the methods that needs to be called from the main method
private void testReadTextFile() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String FileLine = null;
while ((FileLine = reader.readLine()) != null) {
locatedFileName(FileLine,fileName,MyFileList); //test to see if the "./ Add name=" is found in any of the strings
}
}
private void printArrayFileList(ArrayList<String> myList) {
for (String myIndexFileListVariable : myList) {
System.out.println("File Name: " + myIndexFileListVariable);
}
}
}
// --- <<IS-END-SHARED-SOURCE-AREA>> ---
}
your inner class is not static, try
public static class GetTheFileListClass { ....
The rules of scope still apply, even though GetTheFileListClass is (a) a class and is (b) public. Because it is declared inside of ReturnListOfValidFileNames_SVC, that is its enclosing class, so any non-static reference to it must follow the rules of scope.
So you have two options (I'm using main to simulate your static method):
Declare the inner class static:
public final class Outer {
public static void main(String[] args) {
Inner inner = new Inner ();
inner.doIt();
}
public static class Inner {
public void doIt() {
System.out.println("Do it");
}
}
}
OR
Within your static method, create an instance of the enclosing class and use the new operator on it like this
public final class Outer {
public static void main(String[] args) {
Outer outer = new Outer();// Now we have an enclosing instance!
Inner inner = outer.new Inner ();
inner.doIt();
}
public class Inner {
public void doIt() {
System.out.println("Do it");
}
}
}
Have fun!
This is related to the following question:
How to improve the builder pattern?
I'm curious whether it's possible to implement a builder with the following properties:
Some or all parameters are required
No method receives many parameters (i.e., no list of defaults supplied to the initial builder factory method)
All builder fields can be reassigned an arbitrary number of times
The compiler should check that all parameters have been set
It is ok to require that parameters are initially set in some order, but once any parameter is set, all following builders can have this parameter set again (i.e., you can reassign the value of any field of the builder you wish)
No duplicate code should exist for setters (e.g., no overriding setter methods in builder subtypes)
One failed attempt is below (empty private constructors omitted). Consider the following toy builder implementation, and note that line with "Foo f2" has a compiler error because the inherited setter for a returns a BuilderB, not a BuilderFinal. Is there a way to use the java type system to parameterize the return types of the setters to achieve the above goals, or achieve them some other way.
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA newBuilder() {
return new BuilderC();
}
public static class BuilderA {
private volatile int a;
public BuilderB a(int v) {
a = v;
return (BuilderB) this;
}
public int a() {
return a;
}
}
public static class BuilderB extends BuilderA {
private volatile int b;
public BuilderC b(int v) {
b = v;
return (BuilderC) this;
}
public int b() {
return b;
}
}
public static class BuilderC extends BuilderB {
private volatile int c;
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}
Your requirements are really hard, but see if this generic solution fits the bill:
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA<? extends BuilderB<?>> newBuilder() {
return new BuilderFinal();
}
public static class BuilderA<T extends BuilderB<?>> {
private volatile int a;
#SuppressWarnings("unchecked")
public T a(int v) {
a = v;
return (T) this;
}
public int a() {
return a;
}
}
public static class BuilderB<T extends BuilderC<?>> extends BuilderA<T> {
private volatile int b;
#SuppressWarnings("unchecked")
public T b(int v) {
b = v;
return (T) this;
}
public int b() {
return b;
}
}
public static class BuilderC<T extends BuilderFinal> extends BuilderB<T> {
private volatile int c;
#SuppressWarnings("unchecked")
public T c(int v) {
c = v;
return (T) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC<BuilderFinal> {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}
To my knowledge the builder pattern should be used in case multiple parameters are used that make the invocation rather complicated as parameters might swap positions or not make it obviously clear what which parameter is for.
A rule of thumb would be to require compulsory parameters within the constructor of the builder and optional parameters within the methods. However, often more than 4 parameters may be required which makes the invocation again rather unclear and the pattern redundant. So a split up into default constructor and parameter setting for each parameter can also be used.
The checks should happen in a own method which is invoked within the build-method so you could invoke it using super. Compile-time security is only guaranteed on the correct data types (only exception - null is possible to, this has to be fetched within the checkParameters()-method). You can however force that all required parameters are set on requiring them within the Builder constructor - but as mentioned before, this may lead to a redundant pattern.
import java.util.ArrayList;
import java.util.List;
public class C
{
public static class Builder<T extends C, B extends C.Builder<? extends C,? extends B>> extends AbstractBuilder<C>
{
protected String comp1;
protected String comp2;
protected int comp3;
protected int comp4;
protected int comp5;
protected List<Object> comp6 = new ArrayList<>();
protected String optional1;
protected List<Object> optional2 = new ArrayList<>();
public Builder()
{
}
public B withComp1(String comp1)
{
this.comp1 = comp1;
return (B)this;
}
public B withComp2(String comp2)
{
this.comp2 = comp2;
return (B)this;
}
public B withComp3(int comp3)
{
this.comp3 = comp3;
return (B)this;
}
public B withComp4(int comp4)
{
this.comp4 = comp4;
return (B)this;
}
public B withComp5(int comp5)
{
this.comp5 = comp5;
return (B)this;
}
public B withComp6(Object comp6)
{
this.comp6.add(comp6);
return (B)this;
}
public B withOptional1(String optional1)
{
this.optional1 = optional1;
return (B)this;
}
public B withOptional2(Object optional2)
{
this.optional2.add(optional2);
return (B)this;
}
#Override
protected void checkParameters() throws BuildException
{
if (this.comp1 == null)
throw new BuildException("Comp1 violates the rules");
if (this.comp2 == null)
throw new BuildException("Comp2 violates the rules");
if (this.comp3 == 0)
throw new BuildException("Comp3 violates the rules");
if (this.comp4 == 0)
throw new BuildException("Comp4 violates the rules");
if (this.comp5 == 0)
throw new BuildException("Comp5 violates the rules");
if (this.comp6 == null)
throw new BuildException("Comp6 violates the rules");
}
#Override
public T build() throws BuildException
{
this.checkParameters();
C c = new C(this.comp1, this.comp2,this.comp3, this.comp4, this.comp5, this.comp6);
c.setOptional1(this.optional1);
c.setOptional2(this.optional2);
return (T)c;
}
}
private final String comp1;
private final String comp2;
private final int comp3;
private final int comp4;
private final int comp5;
private final List<?> comp6;
private String optional1;
private List<?> optional2;
protected C(String comp1, String comp2, int comp3, int comp4, int comp5, List<?> comp6)
{
this.comp1 = comp1;
this.comp2 = comp2;
this.comp3 = comp3;
this.comp4 = comp4;
this.comp5 = comp5;
this.comp6 = comp6;
}
public void setOptional1(String optional1)
{
this.optional1 = optional1;
}
public void setOptional2(List<?> optional2)
{
this.optional2 = optional2;
}
// further methods omitted
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(this.comp1);
sb.append(", ");
sb.append(this.comp2);
sb.append(", ");
sb.append(this.comp3);
sb.append(", ");
sb.append(this.comp4);
sb.append(", ");
sb.append(this.comp5);
sb.append(", ");
sb.append(this.comp6);
return sb.toString();
}
}
On extending D from C and also the builder, you need to override the checkParameters() and build() method. Due to the use of Generics the correct type will be return on invoking build()
import java.util.List;
public class D extends C
{
public static class Builder<T extends D, B extends D.Builder<? extends D, ? extends B>> extends C.Builder<D, Builder<D, B>>
{
protected String comp7;
public Builder()
{
}
public B withComp7(String comp7)
{
this.comp7 = comp7;
return (B)this;
}
#Override
public void checkParameters() throws BuildException
{
super.checkParameters();
if (comp7 == null)
throw new BuildException("Comp7 violates the rules");
}
#Override
public T build() throws BuildException
{
this.checkParameters();
D d = new D(this.comp1, this.comp2, this.comp3, this.comp4, this.comp5, this.comp6, this.comp7);
if (this.optional1 != null)
d.setOptional1(optional1);
if (this.optional2 != null)
d.setOptional2(optional2);
return (T)d;
}
}
protected String comp7;
protected D(String comp1, String comp2, int comp3, int comp4, int comp5, List<?> comp6, String comp7)
{
super(comp1, comp2, comp3, comp4, comp5, comp6);
this.comp7 = comp7;
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(super.toString());
sb.append(", ");
sb.append(this.comp7);
return sb.toString();
}
}
The abstract builder class is quite simple:
public abstract class AbstractBuilder<T>
{
protected abstract void checkParameters() throws BuildException;
public abstract <T> T build() throws BuildException;
}
The exception is simple too:
public class BuildException extends Exception
{
public BuildException(String msg)
{
super(msg);
}
}
And last but not least the main method:
public static void main(String ... args)
{
try
{
C c = new C.Builder<>().withComp1("a1").withComp2("a2").withComp3(1)
.withComp4(4).withComp5(5).withComp6("lala").build();
System.out.println("c: " + c);
D d = new D.Builder<>().withComp1("d1").withComp2("d2").withComp3(3)
.withComp4(4).withComp5(5).withComp6("lala").withComp7("d7").build();
System.out.println("d: " + d);
C c2 = new C.Builder<>().withComp1("a1").withComp3(1)
.withComp4(4).withComp5(5).withComp6("lala").build();
System.out.println(c2);
}
catch (Exception e)
{
e.printStackTrace();
}
}
Output:
c: a1, a2, 1, 4, 5, [lala]
d: d1, d2, 3, 4, 5, [lala], d7
Builders.BuildException: Comp2 violates the rules
... // StackTrace omitted
Though, before messing to much with Generics I'd suggest to stick to the KISS policy and forget inheritance for builders and code them simple and stupid (with part of them including dumb copy&paste)
#edit: OK, after all the work done and re-reading the OP as well as the linked post I had a totally wrong assumption of the requirements - like a German wording says: "Operation successful, patient is dead" - though I leave this post here in case someone wants a copy&paste like solution for a builder-inheritance which actually returns the correct type instead of the the base type
I had a crazy idea once, and it kind of goes against some of your requirements, but I think you can have the builder constructor take the required parameters, but in a way that makes it still clear which parameters are being set. Take a look:
package myapp;
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static class Builder {
private int a;
private int b;
private int c;
public Builder(A a, B b, C c) {
this.a = a.v;
this.b = b.v;
this.c = c.v;
}
public Builder a(int v) { a = v; return this; }
public Builder b(int v) { b = v; return this; }
public Builder c(int v) { c = v; return this; }
public Foo build() {
return new Foo(a, b, c);
}
}
private static class V {
int v;
V(int v) { this.v = v; }
}
public static class A extends V { A(int v) { super(v); } }
public static class B extends V { B(int v) { super(v); } }
public static class C extends V { C(int v) { super(v); } }
public static A a(int v) { return new A(v); }
public static B b(int v) { return new B(v); }
public static C c(int v) { return new C(v); }
public static void main(String[] args) {
Foo f1 = new Builder(a(1), b(2), c(3)).build();
Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
}
}
For other clients, static imports are your friends:
package myotherapp;
import myapp.Foo;
import static myapp.Foo.*;
public class Program {
public static void main(String[] args) {
Foo f1 = new Builder(a(1), b(2), c(3)).build();
Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
}
}
Building on Jordão's idea, I came up with the following, which may arguably satisfy all requirements 1-6 even though there is some duplicate code in the type parameters. Essentially, the idea is to "pass around" the return types of each method by using type parameters to override the return value of the inherited methods. Even though the code is verbose and impractical, and actually requires Omega(n^3) characters if you extend it out to an arbitrary number of fields n, I'm posting it because I think it's an interesting use of the java type system. If anyone can find a way to reduce the number of type parameters (especially asymptotically), please post in the comments or write another answer.
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA<? extends BuilderB<?, ?>, ? extends BuilderC<?, ?>> newBuilder() {
return new BuilderFinal();
}
public static class BuilderA<B extends BuilderB<?, ?>, C extends BuilderC<?, ?>> {
private volatile int a;
#SuppressWarnings("unchecked")
public B a(int v) {
a = v;
return (B) this;
}
public int a() {
return a;
}
}
public static class BuilderB<B extends BuilderB<?, ?>, C extends BuilderC<?, ?>> extends BuilderA<B, C> {
private volatile int b;
#SuppressWarnings("unchecked")
public C b(int v) {
b = v;
return (C) this;
}
public int b() {
return b;
}
}
public static class BuilderC<B extends BuilderC<?, ?>, C extends BuilderC<?, ?>> extends BuilderB<B, C> {
private volatile int c;
#SuppressWarnings("unchecked")
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC<BuilderFinal, BuilderFinal> {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).a(2).build();
Foo f2 = newBuilder().a(1).a(2).c(3).build(); // compile error
Foo f3 = newBuilder().a(1).b(2).a(3).b(4).b(5).build(); // compile error
}
}
Why don't you want to override the setters in BuilderFinal? They would just need to downcast the super method:
public static class BuilderFinal extends BuilderC {
#Override
public BuilderFinal a(int v) {
return (BuilderFinal) super.a(v);
}
#Override
public BuilderFinal b(int v) {
return (BuilderFinal) super.b(v);
}
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
class A {
static int i;
{
System.out.println("A init block"+ ++i);
}
}
class B extends A {
static int j;
{
System.out.println("B init block"+ ++j);
}
}
class C extends B {
static int k;
{
System.out.println("C init block"+ ++k);
}
public static void main(String abc[])
{
C c =new C();
}
}
In the code above, we can easily count the number of objects created for each class.
But if i want to check the number of object created explicitly , i mean if I create C's object using new C(), or B's object using new B(), then it should give the count accordingly
Take for example,
C c2=new C();
B b2=new B();
So it should give the output of B's count as 1 and not 2.
public class Foo {
private static int fooCount = 0;
public Foo() {
if (this.getClass() == Foo.class) {
fooCount++;
}
}
public static int getFooCount() {
return fooCount;
}
}
public class Test {
static int count;
Test() {
count++;
}
public static void main(String[] args) {
Test t = new Test();
Test t1 = new Test();
NewTest nt = new NewTest();
System.out.println("Test Count : " + Test.count);
System.out.println("NewTest Count : " + NewTest.count);
}
}
class NewTest extends Test
{ static int count;
NewTest()
{
Test.count--;
NewTest.count++;
}
}
OP :
Test Count : 2
NewTest Count : 1