Lets say you have a class SomeClass which has its own implementation of toString(), and also has the ability to parse a new instance of itself by reading that same string.
Which of these methods do you prefer, or find better to use?
You can either define it as another constructor:
public SomeClass(String serializedString);
or you can define it as a static method, which in turn creates a new instance (by one of the other constructors, does some with it, and returns the new instance:
public static SomeClass toObject(String serializedString);
Does it even matter? (my hunch is there is no case this matters, but I am trying to make sure)
My own preference is to keep the parsing logic out of the constructor. That way it can call the appropriate constructors (possibly private) as necessary. It doesn't have to depend on default object construction and so on. So I would go with the toSomeClass() method.
Also, it is not immediately clear that SomeClass(String) will parse an object based on the serialization string. There may be many other meanings to a constructor which takes a String. The toSomeClass() static method makes this clear.
I agree with Avi's recommendation. I'd like to add two more advantages:
A static factory method allows you to return null, which a constructor can't.
A static factory method allows you to return a subclass of its defined return type, which can help provide forward compatibility.
One exception: if you're writing a simple value type and using the immutable pattern, I see no reason to use a static factory method.
The static method has the advantage that you can then use the string-reading constructor for something else. Also in general it's better to use static factories than constructors in any nontrivial classes. It gives you more flexibility.
A Java convention for such static methods is:
public class Foo {
// ...
public Foo parseFoo (String s) {...}
// ...
}
as in the standard parseInt(...), parseLong(...), parseDouble(...), etc. Unfortunately, Sun also gave us a different convention with the wrapper classes, as in Boolean.valueOf(...). However, I'd pick one of those conventions and follow it consistently.
To keep some specific logic (like parsing from string) out of constructor is good design policy.
Constructor job is mainly object creation. Initialization and creation of it's fields.
Serialization logic need to be separated from creation. Firstly you may wan't to create separate static method, secondly in evolution of your class you may want to implement some kind of Serializable interface and delegate reading/writing job to another class.
Another advantage to a static constructor is that you can give it a meaningful name. In this case, I would suggest parse:
SomeClass inst = SomeClass.parse("wibble");
Related
private static <T> String mapQueryResults(T objNew) {
T obj = new T();
...
}
It gives me error "Cannot instantiate the type T". How can I create an instance? Thanks
You cannot do this. Type T could be any type, including interfaces and abstract classes, which cannot be instantiated themselves. Even if a non-abstract class is passed, the empty constructor might not exist. If you wish to pass something to be able to create new instances of some class, then you could pass some factory class that creates these new instances for you through some method.
When topics like these come up, my approach is "forget programming and think logically."
The OP asked
create an instance by only using the passed parameter generic type
Basically, you want a constructor to build a concrete thing based on something generic. Is this possible in real life? Say that you need "something" built and you go to a builder and you tell the builder "I want you to build something for me" and provide no context, no additional information. Is it realistic to expect that the builder will be able to build what you need? Of course the answer is no. Unless you specify in sufficient detail a description of what you want, the builder is not going to know what to build.
T or "type", as others already mentioned, could be anything. If this was allowed by the language, you will most likely end up with nothing usable. It would be like having T be dough. Unless you specifically tell someone you want pizza, or bread, or flour tortillas, there is no way you can expect someone to make what you want if the only thing that is known is "dough."
Different "types" have different requirements for construction. In fact, some "types" cannot be built at all (they might have a private constructor). Others the constructor is hidden behind static factory methods. In short, there are too many reasons why this is simply not possible.
All that said, you are not really wrong thinking that there should be a way where you can pass a set of different "types" of parameters to some function and end up with different kinds of concrete objects built. If that is what you are thinking, then what you need is a Design Pattern (or patterns) that will support this notion.
In the original Gang of Four book, you will find 5 CREATIONAL Design Patterns:
Abstract Factory - factory that builds family of things (i.e. a factory of factories)
Builder - Builds the object in stages (typically when objects are too complex)
Factory Method - factory that build single type of object (or different things based on a common abstraction)
Prototype - Creates a new object based on another object
Singleton - Ensures a single instance is created
Based on the little information in the original post, I believe the OP needs to implement either a Factory Method or possibly a Prototype pattern.
You could change the method argument to accept a Supplier<T> constructor function, and pass in something like MyClass::new:
public class MyClass {
public MyClass() {}
public MyClass(String s) { ... }
}
public static void main(String[] args) {
mapQueryResults(MyClass::new);
mapQueryResults(() -> new MyClass("test"));
}
private static <T> String mapQueryResults(Supplier<T> objNew) {
T obj = objNew.get();
...
}
I want to invoke the static method of a class without putting any object in the context of JEXL.
For instance methods, we put an object to the MapContext and use the key to call the method. but In my case, I don't have anything in context. ${person.howYouDoing()} I don't want to use person object to put in the context.
There's a good discussion of this as a JEXL improvement at https://issues.apache.org/jira/browse/JEXL-140.
The guy who requested this proposed a solution that puts the burden on the JEXL programmer. It creates a String only to get the String class, which is only used to look up the desired class.
${''.class.forName('person').howYouDoing()}
...assuming that "person" is in the default package. This can be used to call static constructors for classes like Pattern for which there is no public constructor:
${''.class.forName('java.util.regex.Pattern').compile('\\d{2}-(\\w{3})-\\d{2}')}
By the way, the JEXL developers suggested subclassing JexlContext to always return any class which exists. This is more elegant than requiring your template writers do the ''.class.forName() hack, but since you didn't want to modify your MapContext, it might not satisfy your question. It also pollutes your context with all classes.
From the documentation:
ns:function A JexlEngine can register objects or classes used as
function namespaces. This can allow expressions like:
math:cosinus(23.0)
https://commons.apache.org/proper/commons-jexl/reference/syntax.html
So you have to register a class with JexlEngine
There is no problem to call a static method from anywhere. Check you have imported the class of the static method and it is in the classpath.
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.
Back couple of months ago I attended a presentation hosted by two representative of an independent software development company. It was mainly about good software design and practices.
The two guys were talking mainly about Java and I remember them saying, that in some circumstances it is very good practice to use getInstanceOf() instead of the constructor. It had something to do with making always calling getInstanceOf() from different classes rather than constructor and how it was it is much better approach on larger scale projects.
As you can see I cannot remember much from it now :/ but I remember that the arguments that they used were really convincing. I wonder if any of you ever came across such a design and when, would you say, is it useful? Or do you think it isn't at all?
Consider static factory methods instead of constructors—Joshua Bloch
They were probably talking about the static factory method pattern (and not the reflection API method for dynamically creating objects).
There at several advantages of a method such as getInstanceOf() over a constructor and using new. The static factory method can...
Choose to create a different sub-class of the main class if that is desirable in certain cases (based on environmental conditions, such as properties and other objects/singletons, or method parameters).
Choose to return an existing object instead of creating one. For an example of this, see Boolean.valueOf(boolean) in the Java API.
Do the same thing as the constructor - just return a new instance of the class itself.
Provide many different kinds of ways to construct a new object and name those methods so they are less confusing (e.g. try this with constructors and you soon have many different overloads). Sometimes this is not even possible with constructors if you need to be able to create an instance two different ways but only need the same type of parameters. Example:
// This class will not compile!
public class MyClass {
public MyClass(String name, int max) {
//init here
}
public MyClass(String name, int age) {
// init here
}
}
// This class will compile.
public class MyClass2 {
private MyClass2() {
}
public static MyClass2 getInstanceOfMax(String name, int max) {
MyClass2 m2 = new MyClass2();
// init here
return m2;
}
public static MyClass2 getInstanceOfAge(String name, int age) {
MyClass2 m2 = new MyClass2();
// init here
return m2;
}
}
Do any combination of the above.
And, on top of all that it hides the detail of instantiating an instance from other classes and so can be varied in the future (construction encapsulation).
A constructor can only ever create a new instance of an object of the exact type requested. It cannot be varied later.
Some disadvantages of this pattern are:
The factory methods are static so cannot be inherited in sub-classes; a parent constructor is easily accessible to sub-classes.
The factory method names can vary widely and this could be confusing for some (new) developers.
You also asked for personal experience. Yes, I frequently use both patterns. For most classes constructor but when there are much more advanced needs then I use the static factory. I also work on projects in other languages (proprietary, but similar to Java) where this form of construction is mandated.
I suspect you mean the newInstance method on the Class class. You would invoke it like this: MyClass foo = MyClass.newInstance();
This form of object instantiation is popular in creational patterns; it's useful when you want to specify the concrete, runtime type of an object externally, such as in a properties or XML file.
If Drew is right, newInstance() is part of the Java Reflection API. So it is not as natural as using a constructor.
Why it would be recommended to use it on a large project may come with the fact that it leads to Java Bean programming style and clearly makes the creation of the object something particular. On large project, creating object shouldn't be a cross-cutting concern but rather a clearly identified responsibility, often from one source / factory. But IMHO, you get all of those advantages and many more with IoC pattern.